`
Dead_knight
  • 浏览: 1200991 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
752c8642-b795-3fe6-946e-a4e845bffdec
Spring Securi...
浏览量:240195
33caa84e-18a6-3036-a82b-6e2106a4de63
clojure专题
浏览量:48915
E17ca077-44df-3816-a3fe-471c43f6e1e5
WebLogic11g
浏览量:236876
社区版块
存档分类
最新评论

Spring Security3源码分析-SSL支持

 
阅读更多

Sping Security3对于SSL的支持仅仅表现在对需要拦截的url(标签intercept-url)设置requires-channel=https属性。

如果一个url设置了requires-channel为https,那么该url在http的访问会直接重定向到https的通道中去。后面再具体分析。

首先需要在应用中配置SSL的支持,具体配置方法可参考

http://lengyun3566.iteye.com/blog/1141347

 

Sping Security3支持SSL分别表现下面几个类

 

类名称 用途描述
ChannelProcessingFilter 通道处理过滤器。只要intercept-url标签中包含requires-channel属性,该过滤器就被创建
ChannelDecisionManagerImpl 通道决策管理器。该管理器包含两个ChannelProcessor实例用于处理安全、不安全两种Channel方式
SecureChannelProcessor 安全通道处理器
InsecureChannelProcessor

不安全通道处理器

AbstractRetryEntryPoint 抽象的通道重操作入口点,是entrypoint的父类
RetryWithHttpEntryPoint 如果当前以安全通道访问不安全通道,也可以通过http的入口点重定向到不安全通道中
RetryWithHttpsEntryPoint 如果当前以不安全通道访问安全通道,就要通过https的入口点重定向到安全通道中
PortMapperImpl 端口映射处理。主要是针对非默认端口(80、8080、443、8443)的情况

 

 看ChannelProcessingFilter过滤器的作用

ChannelProcessingFilter首先检查当前请求的url是否已配置了requires-channel属性,如果没配置,不处理。如果配置了,就把决策权交给ChannelDecisionManagerImpl处理。

ChannelProcessingFilter对应类路径:org.springframework.security.web.access.channel.ChannelProcessingFilter

具体源码如下

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        FilterInvocation fi = new FilterInvocation(request, response, chain);
        //获取url的权限配置信息
        Collection<ConfigAttribute> attr = this.securityMetadataSource.getAttributes(fi);

        if (attr != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Request: " + fi.toString() + "; ConfigAttributes: " + attr);
            }
            //把决策权交给channelDecisionManager处理
            channelDecisionManager.decide(fi, attr);

            if (fi.getResponse().isCommitted()) {
                return;
            }
        }

        chain.doFilter(request, response);
    }

 接着看ChannelDecisionManagerImpl的作用

ChannelDecisionManagerImpl根据requires-channel的值做相应处理,requires-channel值有以下三种

any:任何通道都支持。决策管理器不做处理

https:只支持安全通道。决策管理器把决策任务交给ChannelProcessor列表循环处理

http:只支持http。决策管理器把决策任务交给ChannelProcessor列表循环处理

ChannelDecisionManagerImpl的源码为:

    public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException {

        Iterator<ConfigAttribute> attrs = config.iterator();
        //判断是否为any值
        while (attrs.hasNext()) {
            ConfigAttribute attribute = attrs.next();
            if (ANY_CHANNEL.equals(attribute.getAttribute())) {
                return;
            }
        }
        //循环ChannelProcessor列表执行decide
        for (ChannelProcessor processor : channelProcessors) {
            processor.decide(invocation, config);

            if (invocation.getResponse().isCommitted()) {
                break;
            }
        }
    }

 

继续看ChannelProcessor 的作用

实际上在构造ChannelDecisionManager的bean时,已经注入了两个ChannelProcessor ,分别是SecureChannelProcessor、InsecureChannelProcessor

先看SecureChannelProcessor(负责处理安全通道)执行过程

    public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException {
        Assert.isTrue((invocation != null) && (config != null), "Nulls cannot be provided");
        for (ConfigAttribute attribute : config) {
            if (supports(attribute)) {
                if (!invocation.getHttpRequest().isSecure()) {
                    entryPoint.commence(invocation.getRequest(), invocation.getResponse());
                }
            }
        }
    }

根据当前的请求是否安全,进行相应的处理。实际工作的是抽象的父类AbstractRetryEntryPoint的commence完成

AbstractRetryEntryPoint的commence方法源码:

    public void commence(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException {
        String pathInfo = request.getPathInfo();
        String queryString = request.getQueryString();
        String contextPath = request.getContextPath();
        String destination = request.getServletPath() + ((pathInfo == null) ? "" : pathInfo)
            + ((queryString == null) ? "" : ("?" + queryString));

        String redirectUrl = contextPath;
        //获取当前请求所在端口
     Integer currentPort = new Integer(portResolver.getServerPort(request));
        //根据当前端口获得映射的端口(需要配置port-mappings标签),如果是http的访问,则获取映射的https端口,如果是https的访问,则获取相应的http端口
     Integer redirectPort = getMappedPort(currentPort);
        //如果获取到匹配端口,则根据当前请求构造重定向请求的url
        if (redirectPort != null) {
            boolean includePort = redirectPort.intValue() != standardPort;

            redirectUrl = scheme + request.getServerName() + ((includePort) ? (":" + redirectPort) : "") + contextPath
                + destination;
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Redirecting to: " + redirectUrl);
        }
        //执行重定向操作
        res.sendRedirect(res.encodeRedirectURL(redirectUrl));
    }

通过以上分析,应该很清楚的知道:

如果以http的方式登录到应用中,再访问配置了requires-channel=https的url时,就会重定向到https的通道去,以SSL方式访问。

 

如果以https的方式登录到应用中,再访问配置了requires-channel=http的url时,就会重定向到http的通道去,以不安全的方式访问。

分享到:
评论
7 楼 Dead_knight 2012-08-10  
lintghi 写道
Dead_knight 写道
lintghi 写道
bingfengfzl 写道
我用的是spring security3.11requires-channel="https"配不上,有办法解决不高手可以加你qq不,新人上路。。

我也遇到相似的问题. 用命名空间可以, 但是用自己配置bean的方式, 却提示不能是requires-channel这个属性.

如果自己配置的bean,是不支持requires-channel属性的。因为这是使用spring schema的xsd约束的。
使用命名空间requires-channel="https"也不行么?如果不行,我研究下3.11版本与3.02版本的差异


到最后我是这样配置的:
<bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<property name="securityMetadataSource" ref="defaultFilterInvocationSecurityMetadataSource"/>
<property name="channelDecisionManager" ref="channelDecisionManager"/>
</bean>

<bean id="defaultFilterInvocationSecurityMetadataSource"
class="org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource">
<constructor-arg name="requestMap">
<map>
<entry>
<key>
<bean class="org.springframework.security.web.util.AntPathRequestMatcher">
<constructor-arg name="pattern" value="/login.do"/>
</bean>
</key>
<list>
<bean class="org.springframework.security.access.SecurityConfig">
<constructor-arg name="config" value="REQUIRES_SECURE_CHANNEL"/>
</bean>
</list>
</entry>
</map>
</constructor-arg>
</bean>
上面是配置ChannelProcessFilter.

<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="customAuthenticationManager"/>
<property name="accessDecisionManager" ref="affirmativeBased"/>
<property name="securityMetadataSource">
<security:filter-security-metadata-source id="expressionBasedFilterInvocationSecurityMetadataSource" use-expressions="true" lowercase-comparisons="true">
<security:intercept-url pattern="/login.do" access="permitAll"/>
</security:filter-security-metadata-source>
</property>
</bean>
由于没法使用requires-channel, 所以intercept-url只使用pattern, access属性. filters属性有不能用. 不知道在哪里配置.

目前发现3.1和3.0x的区别是, 用bean方式配置时, 要用构造注入而不是属性注入.

这篇文章没有对SSL的bean初始化进行分析。
最简单的方法,你自己配置bean时,直接打开这个类的源码,查看某个属性是通过构造注入,还是set注入就知道。
Spring Security里面很多类都是构造注入的
6 楼 lintghi 2012-08-10  
Dead_knight 写道
lintghi 写道
bingfengfzl 写道
我用的是spring security3.11requires-channel="https"配不上,有办法解决不高手可以加你qq不,新人上路。。

我也遇到相似的问题. 用命名空间可以, 但是用自己配置bean的方式, 却提示不能是requires-channel这个属性.

如果自己配置的bean,是不支持requires-channel属性的。因为这是使用spring schema的xsd约束的。
使用命名空间requires-channel="https"也不行么?如果不行,我研究下3.11版本与3.02版本的差异


到最后我是这样配置的:
<bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<property name="securityMetadataSource" ref="defaultFilterInvocationSecurityMetadataSource"/>
<property name="channelDecisionManager" ref="channelDecisionManager"/>
</bean>

<bean id="defaultFilterInvocationSecurityMetadataSource"
class="org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource">
<constructor-arg name="requestMap">
<map>
<entry>
<key>
<bean class="org.springframework.security.web.util.AntPathRequestMatcher">
<constructor-arg name="pattern" value="/login.do"/>
</bean>
</key>
<list>
<bean class="org.springframework.security.access.SecurityConfig">
<constructor-arg name="config" value="REQUIRES_SECURE_CHANNEL"/>
</bean>
</list>
</entry>
</map>
</constructor-arg>
</bean>
上面是配置ChannelProcessFilter.

<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="customAuthenticationManager"/>
<property name="accessDecisionManager" ref="affirmativeBased"/>
<property name="securityMetadataSource">
<security:filter-security-metadata-source id="expressionBasedFilterInvocationSecurityMetadataSource" use-expressions="true" lowercase-comparisons="true">
<security:intercept-url pattern="/login.do" access="permitAll"/>
</security:filter-security-metadata-source>
</property>
</bean>
由于没法使用requires-channel, 所以intercept-url只使用pattern, access属性. filters属性有不能用. 不知道在哪里配置.

目前发现3.1和3.0x的区别是, 用bean方式配置时, 要用构造注入而不是属性注入.
5 楼 Dead_knight 2012-08-09  
lintghi 写道
bingfengfzl 写道
我用的是spring security3.11requires-channel="https"配不上,有办法解决不高手可以加你qq不,新人上路。。

我也遇到相似的问题. 用命名空间可以, 但是用自己配置bean的方式, 却提示不能是requires-channel这个属性.

如果自己配置的bean,是不支持requires-channel属性的。因为这是使用spring schema的xsd约束的。
使用命名空间requires-channel="https"也不行么?如果不行,我研究下3.11版本与3.02版本的差异
4 楼 lintghi 2012-08-09  
bingfengfzl 写道
我用的是spring security3.11requires-channel="https"配不上,有办法解决不高手可以加你qq不,新人上路。。

我也遇到相似的问题. 用命名空间可以, 但是用自己配置bean的方式, 却提示不能是requires-channel这个属性.
3 楼 bingfengfzl 2012-08-01  
我用的是spring security3.11requires-channel="https"配不上,有办法解决不高手可以加你qq不,新人上路。。
2 楼 Dead_knight 2012-07-31  
bingfengfzl 写道
求源码,可以贴配置文件出来不?
求源码,小弟不胜感激bingfengfzl@163.com

源码很简单的,仅仅是intercept-url配置中增加requires-channel属性而已
	<security:http auto-config="true" >
		<security:port-mappings>
			<security:port-mapping http="8888" https="8443"/>
		</security:port-mappings>
		<security:form-login login-page="/login.jsp"/>
		<security:logout logout-success-url="/login.jsp" invalidate-session="true"/>
		<security:intercept-url pattern="/login.jsp*" filters="none"/>
		<security:intercept-url pattern="/admin.jsp*" access="ROLE_USER,ROLE_ADMIN"  requires-channel="https"/>
		<security:intercept-url pattern="/UserList.do*" access="ROLE_USER,ROLE_ADMIN"  requires-channel="http"/>
		<security:intercept-url pattern="/index.jsp*" access="ROLE_USER,ROLE_ADMIN"/>
		<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
		<security:session-management session-fixation-protection="none">
		</security:session-management>
	</security:http>
1 楼 bingfengfzl 2012-07-31  
求源码,可以贴配置文件出来不?
求源码,小弟不胜感激bingfengfzl@163.com

相关推荐

    spring security源码分析.pdf

    ### Spring Security 源码分析知识...以上内容涵盖了 Spring Security 3 的源码分析中几个关键点的具体内容。通过对这些内容的深入学习和理解,可以更好地掌握 Spring Security 的工作原理及其在实际项目中的应用技巧。

    spring-security-3.0.3 jar包( 含源码)

    源码分析: 在Spring Security 3.0.3的源码中,开发者可以研究以下关键组件: - `AuthenticationProvider`:处理认证请求的接口,实现它可以自定义认证逻辑。 - `FilterSecurityInterceptor`:AOP拦截器,负责进行...

    《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)附前四章doc文件

    8. Spring Security源码分析:对于深入理解Remember me服务和SSL集成的工作原理,研究Spring Security的源码是很有帮助的。通过阅读源码,开发者可以了解Remember me服务的实现细节,以及如何自定义存储策略和安全...

    4.CXF安全访问之单向SSL或者双向SSL(三)

    对于源码分析,我们可以查看CXF源码中的`org.apache.cxf.transport.http.HTTPConduit`类,了解它是如何处理SSL连接的。同时,`org.apache.cxf.transport.http.security.TransportSecurityConfigurer`接口及其实现类...

    使用cxf和spring开发基于https的webservice服务端以及客户端样例源码.rar

    9. **源码分析**:提供的源码示例应该包含了服务端和客户端的完整实现,包括Spring配置文件、服务接口和实现类、以及测试代码。通过研究这些代码,可以更深入地理解如何结合CXF和Spring来创建和消费基于HTTPS的Web...

    cas-5.2.0源码

    - **Spring框架**:CAS 使用 Spring 框架来构建其核心服务,包括依赖注入、AOP(面向切面编程)和Spring Security,用于实现认证和授权。 - **Web Flow**:CAS 使用 Spring Web Flow 来管理用户交互流程,如登录、...

    基于Java的实例源码-cloudxy(弹性云计算平台 Cloudxy).zip

    云平台的安全性不容忽视,Java的SSL/TLS支持、Spring Security框架等,可能在Cloudxy中扮演重要角色,确保数据传输安全和访问控制。 10. **持续集成与部署(CI/CD)** Cloudxy的开发过程中,可能利用Jenkins、...

    Android应用源码之简易微信客户端和服务器源码-IT计算机-毕业设计.zip

    这篇文档将深入解析...通过学习和分析这份源码,你可以深入理解Android应用的全貌,增强在移动开发领域的实践技能。同时,它也是一个理想的起点,帮助你探索更复杂的应用场景,如群聊、语音/视频通话等功能的实现。

    cxf-2.3.11源码

    7. **安全**:CXF提供了多种安全机制,包括基本认证、 Digest认证、SSL/TLS、WS-Security等,以确保Web服务的安全性。 8. **测试工具**:CXF提供了一套测试工具,如模拟服务器、客户端测试工具,方便开发者进行服务...

    全套源码-即时通信系统(Java实现)

    9. **用户认证与授权**:OAuth 2.0或JWT(JSON Web Tokens)是常见的身份验证机制,Java库如Spring Security或Keycloak可帮助实现这些功能。 10. **并发与性能优化**:Java的并发工具类如ConcurrentHashMap和...

    javaweb项目源码-Java-and-the-Web:课程分配和项目的源代码

    - **Spring Security**:提供认证和授权功能,保护Web应用的安全。 - **HTTPS**:源码可能涉及到SSL/TLS配置,确保数据传输安全。 通过分析这个开源项目,你可以学习到JavaWeb开发的基本流程,包括请求处理、...

    CXF Web Service 安全认证出错?求大牛解决

    - **Spring Security集成**:如果使用Spring Security进行安全控制,确保配置文件中的安全规则正确。 4. **配置错误**: - **CXF配置文件**:检查`cxf.xml`或`cxf-servlet.xml`等配置文件,确保安全相关的元素...

    springboot基于B2B平台的医疗病历交互系统.zip

    - **Spring Security**:Spring Boot可以通过集成Spring Security实现身份验证和授权,保护API免受未授权访问。 - **OAuth2**:可能用OAuth2实现第三方服务的授权,如允许患者授权其他医疗服务提供商访问其病历...

    security-core:安全核心-主动创意技术

    3. **加密**:在Java中,JCA(Java Cryptography Architecture)和JCE(Java Cryptography Extension)提供了加密和哈希算法的支持。安全核心可能会使用这些工具进行数据传输加密、密码存储加密以及敏感信息的加密。...

    java 网上支付源码

    3. **安全机制**:网上支付安全至关重要,Java源码中应包含加密算法(如SSL/TLS、AES等)和安全框架(如Spring Security),用于保护用户的支付信息不被窃取。同时,源码还需包含防止欺诈的策略,如IP黑名单、异常...

    计算机毕业设计-基于java的博客网站系统源码实现

    开发者可以通过阅读和分析源码,了解各部分组件如何协同工作,以及如何实现常见的Web功能,例如用户注册、登录、发表文章、评论互动等。同时,这也是一次实践MVC模式、Spring框架、数据库管理和前端技术融合的好机会...

    基于SpringBoot+vue图书电子商务网站的设计与实现(源码+部署说明+演示视频+源码介绍).zip

    - **关键技术**:深入讲解项目中使用的关键技术,如Spring Security、Spring Cloud等。 - **优化技巧**:分享性能优化、安全防护等方面的实践经验。 通过这个项目,学习者不仅可以掌握SpringBoot和Vue的实战应用...

    基于springboot的课程作业管理系统源码数据库.doc

    - **Spring Security**:用于实现系统的身份验证和授权功能,保障系统安全性。 - **MyBatis**:作为持久层框架,简化数据库操作,提高开发效率。 - **Thymeleaf**:前端模板引擎,用于渲染动态HTML页面。 #### 四、...

    SSO 单点登录(java)

    在Java中,常见的认证中心实现包括Apache Shiro、Spring Security等。 2. **票据(Ticket)**:在SSO中,用户成功登录AC后,AC会生成一个唯一的票据(如:Ticket Granting Ticket, TGT),这个票据可以看作是用户...

    基于ssm+mysql的房屋租赁系统源码数据库论文.docx

    "基于SSM+MySQL的房屋租赁系统源码数据库论文" 在现代社会中,房屋租赁系统扮演着非常重要的角色,它不仅能够满足人们的生活需求,还能够促进房地产行业的发展。本论文基于SSM框架技术,旨在设计和实现一个房屋租赁...

Global site tag (gtag.js) - Google Analytics