收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:5023369
访问用户量:4221
笔记经验:
总积分:261656
级别:VIP5
搜索本笔记
ta的交流分类
ta的交流主题贴(544)
ta的所有交流贴(1049)
ta的全部笔记
全部笔记(255)
未分类笔记(1)
Java Web(9)
并发实践(1)
课程问题(0)
Java(22)
架构(1)
缓存(5)
JavaEE(0)
JVM(12)
跟我学spring3(68)
Spring Sec……(43)
Spring 3.x……(25)
Spring Sec……(20)
跟开涛学Spring……(17)
深入剖析Spring……(18)
性能调优(10)
前端(2)
Tomcat源码解读(1)
spring sec……(0)
存档
2014-01(7)
2013-12(10)
2012-10(4)
2012-09(2)
2012-08(31)
2012-07(10)
2012-06(5)
2012-05(41)
2012-04(3)
2012-03(41)
2012-02(54)
2011-11(17)
2011-10(30)

2012-08-31 10:54:19
SSL支持——Spring Security3源码分析
浏览(11480)|评论(1)   交流分类:Java|笔记分类: Spring Sec……

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

具体源码如下

Java代码    收藏代码
  1. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)  
  2.         throws IOException, ServletException {  
  3.     HttpServletRequest request = (HttpServletRequest) req;  
  4.     HttpServletResponse response = (HttpServletResponse) res;  
  5.   
  6.     FilterInvocation fi = new FilterInvocation(request, response, chain);  
  7.     //获取url的权限配置信息  
  8.     Collection<ConfigAttribute> attr = this.securityMetadataSource.getAttributes(fi);  
  9.   
  10.     if (attr != null) {  
  11.         if (logger.isDebugEnabled()) {  
  12.             logger.debug("Request: " + fi.toString() + "; ConfigAttributes: " + attr);  
  13.         }  
  14.         //把决策权交给channelDecisionManager处理  
  15.         channelDecisionManager.decide(fi, attr);  
  16.   
  17.         if (fi.getResponse().isCommitted()) {  
  18.             return;  
  19.         }  
  20.     }  
  21.   
  22.     chain.doFilter(request, response);  
  23. }  

 接着看ChannelDecisionManagerImpl的作用

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

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

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

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

ChannelDecisionManagerImpl的源码为:

Java代码    收藏代码
  1. public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException {  
  2.   
  3.     Iterator<ConfigAttribute> attrs = config.iterator();  
  4.     //判断是否为any值  
  5.     while (attrs.hasNext()) {  
  6.         ConfigAttribute attribute = attrs.next();  
  7.         if (ANY_CHANNEL.equals(attribute.getAttribute())) {  
  8.             return;  
  9.         }  
  10.     }  
  11.     //循环ChannelProcessor列表执行decide  
  12.     for (ChannelProcessor processor : channelProcessors) {  
  13.         processor.decide(invocation, config);  
  14.   
  15.         if (invocation.getResponse().isCommitted()) {  
  16.             break;  
  17.         }  
  18.     }  
  19. }  

 

继续看ChannelProcessor 的作用

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

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

Java代码    收藏代码
  1. public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException {  
  2.     Assert.isTrue((invocation != null) && (config != null), "Nulls cannot be provided");  
  3.     for (ConfigAttribute attribute : config) {  
  4.         if (supports(attribute)) {  
  5.             if (!invocation.getHttpRequest().isSecure()) {  
  6.                 entryPoint.commence(invocation.getRequest(), invocation.getResponse());  
  7.             }  
  8.         }  
  9.     }  
  10. }  

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

AbstractRetryEntryPoint的commence方法源码:

Java代码    收藏代码
  1. public void commence(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException {  
  2.     String pathInfo = request.getPathInfo();  
  3.     String queryString = request.getQueryString();  
  4.     String contextPath = request.getContextPath();  
  5.     String destination = request.getServletPath() + ((pathInfo == null) ? "" : pathInfo)  
  6.         + ((queryString == null) ? "" : ("?" + queryString));  
  7.   
  8.     String redirectUrl = contextPath;  
  9.     //获取当前请求所在端口  
  10.  Integer currentPort = new Integer(portResolver.getServerPort(request));  
  11.     //根据当前端口获得映射的端口(需要配置port-mappings标签),如果是http的访问,则获取映射的https端口,如果是https的访问,则获取相应的http端口  
  12.  Integer redirectPort = getMappedPort(currentPort);  
  13.     //如果获取到匹配端口,则根据当前请求构造重定向请求的url  
  14.     if (redirectPort != null) {  
  15.         boolean includePort = redirectPort.intValue() != standardPort;  
  16.   
  17.         redirectUrl = scheme + request.getServerName() + ((includePort) ? (":" + redirectPort) : "") + contextPath  
  18.             + destination;  
  19.     }  
  20.   
  21.     if (logger.isDebugEnabled()) {  
  22.         logger.debug("Redirecting to: " + redirectUrl);  
  23.     }  
  24.     //执行重定向操作  
  25.     res.sendRedirect(res.encodeRedirectURL(redirectUrl));  
  26. }  

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

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

 

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

 

 

http://sishuok.com/forum/blogPost/list/0/4314.html

 

转载自【http://dead-knight.iteye.com/blog/1521223

作者博客:http://dead-knight.iteye.com/

精品视频课程推荐

Java数据结构和算法精讲版
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。 从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。

透彻理解JavaBean视频教程
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。

深入浅出学Spring Web MVC视频教程
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识

Weblogic实战视频教程
WebLogic基础知识:WebLogic基本概念、正确安装WebLogic、建域、应用部署于JDBC选择、对WebLogic的监控和日志查看、集群的高可用性;课程目标:彻底掌握WebLogic的基本概念,在理解基本概念的基础上做到正确的安装WebLogic,根据不同的需求创建域,合理选择应用部署和JDBC配置。熟练掌握WebLogic的console监控,了解各种性能和运行指标,以及对监控结果的分析,运用集群的高可用性,对集群架设。

深入浅出学Spring Data JPA视频教程
系统、完整的学习Spring Data JPA开发的知识。包括:Spring Data JPA入门;JpaRepository基本功能 ;JpaRepository的查询;客户化扩展JpaRepository;Specifications查询。

浏览(11480)|评论(1)   交流分类:Java|笔记分类: Spring Sec……

评论(1)
1楼 ludabing  2012-08-31 引用

df

请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网