(HTTPS)-强制 SSL (HTTPS)Filter

汗,无知真可怕,Servlert规范中已经有自动跳转到保护页面(Http - Https)的方法了:

web.xml

<security-constraint>

<display-name>Test Auth</display-name>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<url-pattern>/*</url-pattern> <!-- 整站SSL -->

<http-method>DELETE</http-method>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

</web-resource-collection>

<user-data-constraint>

<description>SSL required</description>

<transport-guarantee>CONFIDENTIAL</transport-guarantee>

</user-data-constraint>

</security-constraint>

Basic 认证 + SSL

<security-constraint>

<display-name>Test Auth</display-name>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<url-pattern>/auth/*</url-pattern>

<http-method>DELETE</http-method>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>ADMIN</role-name>

<role-name>USER</role-name>

</auth-constraint>

<user-data-constraint>

<transport-guarantee>CONFIDENTIAL</transport-guarantee>

</user-data-constraint>

</security-constraint>

回头想想前面的工作真可笑。

--------------------------

在Web工程中,如果使用HTTP Basic认证,或FORM认证,为了安全性,最好使用HTTPS的。

因此我们需要禁止HTTP访问,只能HTTPS访问。

如果大家感兴趣,可以研究下Spring Security(偶也不懂,貌似它能做到HTTPS与HTTP Session共享)。

先了解一下URL和URI在java.net.* 包中的用法和区别。详尽描述请参考Javadoc描述:

URLTest.java

package me.test;

import java.net.URI;

import java.net.URL;

public class URLTest {

public static void main(String[] args) throws Exception {

URL u1 = new URL(

"ftp://zhang3:[email protected]:556/zhang.txt?k1=v1&k2=v2#aa");

System.out.println(u1.toString());

System.out.println(u1.toExternalForm());

System.out.println(u1.toURI());

URL u2 = new URL(

"https",

u1.getHost(),

8443,

u1.getFile());

// 以下三行的数据均为:

// https://192.168.1.1:8443/zhang.txt?k1=v1&k2=v2

System.out.println(u2.toString());

System.out.println(u2.toExternalForm());

System.out.println(u2.toURI());

System.out.println("----------------");

URI i1 = new URI(

"ftp://zhang3:[email protected]:556/zhang.txt?k1=v1&k2=v2#aa");

URI i2 = new URI(

"https",

i1.getUserInfo(),

i1.getHost(),

8443,

i1.getPath(),

i1.getQuery(),

i1.getFragment());

// 以下两行均输出

// https://zhang3:[email protected]:8443/zhang.txt?k1=v1&k2=v2#aa

System.out.println(i2.toURL());

System.out.println(i2.toString());

}

}

以下是偶的Filter:

ForceSSLFilter.java

/*

* @(#)ForceSSLFilter.java

*

* Copyright (c) 2011, Digital Yingtan Construction Committee.

*/

package me.test;

import java.io.IOException;

import java.net.URI;

import java.net.URISyntaxException;

import java.util.ArrayList;

import java.util.List;

import java.util.regex.Pattern;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

/**

* 对某些路径强制使用SSL的Filter。

* 如果请求的URL不是 https,则会使其重定向到相应的https路径上。

*

* 注意:此Filter目前只能用于无状态的WebService等路径。因为https与http在Tomcat等

* Servlet容器中会使用不同的SESSION。

*

* @author 张亮亮 2011/05/26 新建

*/

public class ForceSSLFilter implements Filter {

/** 需要强制使用SSL的路径。 */

protected List<String> sslPaths = null;

/** 不需要强制使用SSL的路径。 */

protected List<String> noSslPaths = null;

/** SSL的端口。 */

protected int sslPort = 443;

/** 是否使用重定向。 */

protected boolean usingRedirect = true;

/**

* 获得初始值。

*

* @param fc 配置信息

*/

public void init(FilterConfig fc) throws ServletException {

// 参数:需要强制使用SSL的路径

String paths = fc.getInitParameter("sslPaths");

sslPaths = new ArrayList<String>();

if (StringUtils.isNotBlank(paths)) {

for (String regexStr : paths.split(",")) {

if (StringUtils.isNotBlank(regexStr)) {

sslPaths.add(regexStr.trim());

}

}

}

// 参数:不需要强制使用SSL的路径

paths = fc.getInitParameter("noSslPaths");

noSslPaths = new ArrayList<String>();

if (StringUtils.isNotBlank(paths)) {

for (String regexStr : paths.split(",")) {

if (StringUtils.isNotBlank(regexStr)) {

noSslPaths.add(regexStr.trim());

}

}

}

// 参数:SSL的端口

String port = fc.getInitParameter("sslPort");

if (StringUtils.isNotBlank(port)) {

sslPort = Integer.valueOf(port);

}

// 参数:是否使用重定向

String redirect = fc.getInitParameter("usingRedirect");

if (StringUtils.isNotBlank(redirect)) {

usingRedirect = Boolean.valueOf(redirect);

}

}

/**

*

*/

public void destroy() {

}

/**

*单点登录主要处理方法。

*

* @param req 请求

* @param resp 响应

* @param filterChain 响应链

*/

public void doFilter(ServletRequest req, ServletResponse resp,

FilterChain filterChain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) resp;

String servletPath = request.getServletPath();

// 不需要SSL?

boolean needFilter = true;

for (String regexStr : noSslPaths) {

if (Pattern.matches(regexStr, servletPath)) {

needFilter = false;

break;

}

}

if (needFilter && !request.isSecure()) {

// 是否需要强制SSL?

boolean needRedirect = false;

for (String regexStr : sslPaths) {

if (Pattern.matches(regexStr, servletPath)) {

needRedirect = true;

break;

}

}

// 进行跳转

if (needRedirect) {

if (usingRedirect) {

try {

URI reqUri = new URI(request.getRequestURL().toString());

URI newUri = new URI("https", reqUri.getUserInfo(),

reqUri.getHost(), sslPort, reqUri.getPath(),

reqUri.getQuery(), reqUri.getFragment());

response.sendRedirect(newUri.toString());

response.flushBuffer();

return;

} catch (URISyntaxException e) {

throw new RuntimeException("请求的URL格式不正确。", e);

}

} else {

response.sendError(403, "此URL必须使用HTTPS访问。");

return;

}

}

}

filterChain.doFilter(request, response);

}

}

web.xml中的配置

...

<filter>

<filter-name>forceSSLFilter</filter-name>

<filter-class>

me.test.ForceSSLFilter

</filter-class>

<init-param>

<param-name>sslPaths</param-name>

<param-value>/auth/.*</param-value>

</init-param>

<init-param>

<param-name>noSslPaths</param-name>

<param-value>/auth/1/.*</param-value>

</init-param>

<init-param>

<param-name>sslPort</param-name>

<param-value>8443</param-value>

</init-param>

<init-param>

<param-name>usingRedirect</param-name>

<param-value>false</param-value>

</init-param>

</filter>

...

不足:Basic认证优先被Servlet容器处理,所以,会造成以下情况;

1. 用户在使用http访问必须要https访问的路径时,被提示输入用户名,密码

2. 然后,显示错误信息(“403 此URL必须使用HTTPS访问” - 如果 web.xml 中usingRedirect为false

或者 跳转到https的访问路径上,但又被要求重新输入一次密码 )

时间: 2024-10-14 10:04:57

(HTTPS)-强制 SSL (HTTPS)Filter的相关文章

2017年iOS应用将强制使用HTTPS安全加密-b

6月14日,WWDC 2016苹果开发者大会上,苹果在讲解全新的iOS10中提到了数据安全这一方面,并且苹果宣布iOS应用将从2017年1月起启用名为App Transport Security的安全传输功能. 2017年所有iOS应用必须支持ATS安全标准,将强制使用HTTPS安全连接: 为什么强制使用ATS 安全标准? ATS 安全标准是苹果在发布 iOS 9 和 OS X EI Capitan 系统时发布的,这一标准通过强行推动一系列安全实际操作,从而积极促进安全性,同时还要求网络请求必须

记录一次给网站服务器添加SSL(https)的过程

都说现在的HTTPS更好,更安全,也给自己的网站添加了HTTPS.以此记录此过程. 访问http://andaily.com试试. -硬件环境 操作系统:   Ubuntu 12.04.1 LTS 服务器:       Apache Server 2.2.22 SSL证书:   沃通免费SSL证书G2  (申请地址https://buy.wosign.com/ApplyForSSL.html选择第一个免费SSL) -主要步骤 1.申请免费SSL后会去下载SSL证书,文件,Apache 的证书文件

centos7安装tengine强制使用HTTPS访问

操作系统:centos7.2 x64tengine:Tengine/2.2.0主机IP: 10.0.0.12 一.安装tengine 1.1 下载源码安装包 1.1.1 源码包pcre-8.40            用于支持正则表达式 [[email protected] ~]# cd /usr/local/src/ [[email protected] src]# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-

苹果强制使用HTTPS传输了怎么办?——关于HTTPS,APP开发者必须知道的事(转)

WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<https大势已来?看腾讯专家如何在高并发压测中支持https>中介绍了腾讯WeTest在基于epoll的高并发机器人框架中加入openssl的方法支持HTTPS接口测试的方法,不仅介绍了具体的使用办法,并且了解到HTTPS注定会是未来的主流趋势. 而随着2016年行将结束,我们发现,这一天,已经越来越近了.

Java调用使用SSL/HTTPS协议来传输的axis webservice服务

使用SSL/HTTPS协议来传输 Web服务也可以使用SSL作为传输协议.虽然JAX-RPC并没有强制规定是否使用SSL协议,但在tomcat 下使用HTTPS协议. 1.使用JDK自带的工具创建密匙库和信任库. 1)通过使用以下的命令来创建服务器端的密匙库: keytool -genkey -alias Server -keystore server.keystore -keyalg RSA 输入keystore密码: changeit 您的名字与姓氏是什么? [Unknown]: Serve

IOS7.1以后企业应用发布强制需要HTTPS协议

一.问题背景 苹果发布IOS7.1以后,企业应用发布强制需要使用HTTPS协议.需要用https协议就需要在服务器上部署SSL证书. 二.问题描述 苹果发布IOS7.1以后,用户安装app,需要使用https协议来下载plist文件,也就是说,在安装app的第一步,下载.plist文件,就需要使用https协议.https协议如下: 用户要使用https来下载.plist文件就需要企业网站支持https协议访问.企业网站如何做到支持HTTPS协议呢?只有在网站服务器上部署SSL证书才能使网站支持

在python使用SSL(HTTPS)

在python上使用SSL有许多场景,我主要关注的是使用python访问HTTPS资源,以及使用python提供HTTPS服务.(HTTPS是SSL在WEB上的应用之一) 一.使用python访问HTTPS网站 这应该算是最简单也是最常见的场景了.我们使用python做为客户端去访问公网上的网站,而这个网站为了传输安全(避免被劫持或者窃听)使用了HTTPS服务,传输过程内容都经过了SSL加密.下面来看下具体的python代码,这里使用的是python2.7.11,用的是python自带的urll

Https协议:SSL建立过程分析(也比较清楚,而且有OpenSSL的代码)

web访问的两种方式: http协议,我们一般情况下是通过它访问web,因为它不要求太多的安全机制,使用起来也简单,很多web站点也只支持这种方式下的访问. https协议(Hypertext Transfer Protocol over Secure Socket Layer),对于安全性要求比较高的情况,可以通过它访问web,比如工商银行https://www.icbc.com.cn/icbc/(当然也可以通过http协议访问,只是没那么安全了).其安全基础是SSL协议. SSL协议,当前版

Https和SSL学习笔记(一)

1. 什么是HTTPS 在说HTTPS之前必须要先说一下HTTP.我们平常浏览网页用的就是HTTP协议,HTTP协议之间传输的数据都是明文,这样对于一些敏感信息传输其实是不安全的,很容易被恶意窃取.应于这样的需求,网景公司设计了SSL协议,用于对HTTP协议传输的数据进行加密,于是HTTPS就此诞生了.SSL的最后一个版本是3.0,之后IETF对SSL3.0进行了升级,于是有了TLS.实际上当前的HTTPS都是用的TLS协议,但SSL依旧被浏览器所支持. 2. HTTPS的工作原理 HTTPS在