汗,无知真可怕,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:123456@192.168.1.1: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:123456@192.168.1.1: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:123456@192.168.1.1: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的访问路径上,但又被要求重新输入一次密码 )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

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

    WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<htt ...

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

    6月14日,WWDC 2016苹果开发者大会上,苹果在讲解全新的iOS10中提到了数据安全这一方面,并且苹果宣布iOS应用将从2017年1月起启用名为App Transport Security的安全 ...

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

    使用SSL/HTTPS协议来传输 Web服务也可以使用SSL作为传输协议.虽然JAX-RPC并没有强制规定是否使用SSL协议,但在tomcat 下使用HTTPS协议. 1.使用JDK自带的工具创建密匙 ...

  4. centos7安装tengine强制使用HTTPS访问

    操作系统:centos7.2 x64tengine:Tengine/2.2.0主机IP: 10.0.0.12 一.安装tengine 1.1 下载源码安装包 1.1.1 源码包pcre-8.40   ...

  5. Java Web学习总结(31)——全站HTTPS化SSL免费证书使用

    1 背景 谷歌从 2017 年起,Chrome 浏览器将也会把采用 HTTP 协议的网站标记为「不安全」网站:苹果从 2017 年 iOS App 将强制使用 HTTPS:在国内热火朝天的小程序也要求 ...

  6. iOS应用将强制使用HTTPS安全加密-afn配置https(190926更新)

    WWDC 2016苹果开发者大会上,苹果在讲解全新的iOS10中提到了数据安全这一方面,并且苹果宣布iOS应用将从2017年1月起启用名为App Transport Security的安全传输功能. ...

  7. 聊聊HTTPS和SSL/TLS协议

    要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识.1. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义2. 大致了解 HTTP 和 TCP 的关系(尤其是“短连接”VS“长连接 ...

  8. 浅谈HTTPS和SSL/TLS协议的背景和基础

    相关背景知识要说清楚HTTPS协议的实现原理,至少要需要如下几个背景知识.大致了解几个基础术语(HTTPS.SSL.TLS)的含义大致了解HTTP和TCP的关系(尤其是"短连接"和 ...

  9. 浅谈 HTTPS 和 SSL/TLS 协议的背景与基础

    来自:编程随想   >> 相关背景知识 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义 大致了解 HTTP 和 ...

随机推荐

  1. 网络语音视频技术浅议(附多个demo源码下载)

    我们在开发实践中常常会涉及到网络语音视频技术.诸如即时通讯.视频会议.远程医疗.远程教育.网络监控等等,这些网络多媒体应用系统都离不开网络语音视频技术.本人才疏学浅,对于网络语音视频技术也仅仅是略知皮 ...

  2. 前端随手优化不完全篇-SEO篇

    一代码优化概述 关于代码优化的知识是纯理论的知识,学习的很枯燥.在学到CSS时,不免遇到CSS+div进行代码优化的知 识,因此在网上看了一些关于这方面的知识,简单的整合一下,梳理自己所了解的代码优化 ...

  3. NodeJs系列一:神奇的nodejs

    nodejs是什么 nodejs能解决什么问题 非阻塞型I/O及事件环机制 什么时候使用nodejs nodejs是什么 Node.js是让Javascript脱离浏览器运行在服务器的一个平台(或者叫 ...

  4. 谁用光了磁盘?Docker System命令详解

    译者按: Docker镜像,容器,数据卷以及网络都会占用主机的磁盘空间,这样的话,磁盘很容易就会被用完.这篇博客介绍了一个简单的解决方案 - Docker System命令. 原文: What's e ...

  5. 【知识必备】浅淡MVP在Android项目中的实战演习,让代码结构更简单~

    一.写在前面 讲道理,这次是真的笔者很久都没有更新blog了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里 ...

  6. python——文件操作

    open函数,该函数用于文件处理 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 1 文件句柄 = open('文件路径', '模式') 打开文件时,需要指定文件路径和以何等方式 ...

  7. EzHttp 流传输调用代码示例

    EzHttp框架提供的内置接口,用于文件流等传输 流传输调用代码示例 内置接口: public interface IEzStreamHandler { Task<byte[]> GetD ...

  8. Jmeter察看结果树的响应数据中的中文显示乱码问题处理

    1.Jmeter的察看结果树的响应数据有中文时会显示乱码,如图,我访问百度HTTP请求,响应数据中的title处是一串乱码 2.我们需要改一个设置,打开jmeter\bin\jmeter.proper ...

  9. 进程间通信系列 之 socket套接字实例

    进程间通信系列 之 概述与对比   http://blog.csdn.net/younger_china/article/details/15808685  进程间通信系列 之 共享内存及其实例   ...

  10. 大数相加a+b

    #include<stdio.h>#include<string.h>#define MAX 1000void Add(char *a,char *b,char *result ...