收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:5106296
访问用户量:4228
笔记经验:
总积分: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源码分析
浏览(11596)|评论(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/

精品视频课程推荐

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

Ajax+JSON基础实战视频教程
数据校验、Javascript模拟多线程、下拉列表联动、操作XML、AJAX结合JSON的操作、Json-lib的使用

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

高级软件架构师实战培训阶段一
内容概述:本课程专注于构建:高可扩展性、高性能、大数据量、高并发、分布式的系统架构。 从零开始、全面系统、成体系的软件架构课程,循序渐进的讲述构建上述系统架构所需要的各种技术知识和技能。
技术要点: 1:构建基本的业务功能块,基于Maven+Git+Spring mvc+spring+mybatis+ehcache+mysql+X-gen代码生成
 2:高扩展性的分布式体系架构(基于Nginx+Varnish+Memcache+ActiveMQ)
 3:NoSQL的合理使用和架构优化(基于MongoDB)
 4:分布式文件存储和架构优化(基于MogileFS)

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

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

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

df

请登录后评论 登录

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

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