收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:5023380
访问用户量: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-03-23 08:44:28
《Spring Security 3》 【第六章】 高级配置和扩展(7)
浏览(10355)|评论(0)   交流分类:Java|笔记分类: Spring Sec……

认证事件处理

有一个重要的功能只能通过基于bean的配置就是自定义处理认证事件。认证事件使用了Spring的时间发布机制,它基于o.s.context.ApplicationEvent事件模型。Spring事件模型使用并不广泛,却能够很有用处——特别在认证系统中——如当你想绑定特定行为到认证领域的行动上去的时候。

 

事件是典型的订阅-发布模式,通知订阅者是Spring运行环境自己处理的。比较重要的一点是,在默认情况下Spring的事件模型是同步的,所以有任何订阅监听的运行时会直接影响产生事件请求的性能。

 

在ApplicationContext初始化的时候,Spring将会检查所有配置的bean是否存在o.s.context.ApplicationListener接口。这些bean的引用将会被o.s.context.event.ApplicationEventMulticaster持有,它会在o.s.context.ApplicationEventPublisher发布事件时,管理运行时事件的发布。这个设施已经存在很长时间了(从Spring1.1),所以你若想更深入了解Spring的这个领域,有很多文档可查。

 

下图阐述了事件发布流程是如何组织在一起的:




因为在Spring Security内部没有广泛使用认证事件(实际上,唯一明显用的地方就是我们本章前面讨论的session并发跟踪),自定义认证事件的监听器是一种实现审计、管理报警甚至复杂用户行为追踪的便利方式。

 

让我们了解一下配置简单安全事件监听的过程。

 

配置认证事件的监听器

使用简短的security命名空间配置,你不能配置认证事件监听器——它必须使用基于Spring bean的方式因为ApplicationEventPublisher的实现类默认不会启用,必须织入到AuthenticationManager中。

声明需要的bean依赖

我们首先声明ApplicationEventPublisher的实现类,如下:

 

java代码:
<bean id="defaultAuthEventPublisher"   
  class="org.springframework.security.authentication .DefaultAuthenticationEventPublisher"/>  

 

接下来,我们将会把它织入到使用的AuthenticationManager中:

 

java代码:
<bean id="customAuthenticationManager"   
  class="org.springframework.security.authentication.ProviderManager">  
  <property name="authenticationEventPublisher" ref="defaultAuthEventPublisher"/>  
  <property name="providers">  
    <list>  
      <ref local="daoAuthenticationProvider"/>  
      <ref local="rememberMeAuthenticationProvider"/>  
    </list>  
  </property>  
</bean> 

 

这就是全部需要的配置。如果此时你重启应用,你将会什么也看不到。这是因为我们还没有创建bean来监听发布的时间。现在,我们就做这件事。

构建自定义的应用事件监听器

ApplicationListener的实现类很简单,并且使用Spring 3加入的强大Java泛型功能支持类型安全。我们的ApplicationListener只是简单记录收到的事件到标准输出中,但是在后面的练习中我们将会体验一个更有趣的例子。

 

自定义的ApplicationListener如下:

 

java代码:
package com.packtpub.springsecurity.security;  
// imports omitted  
  @Component  
  public class CustomAuthenticationEventListener implements  
    ApplicationListener<AbstractAuthenticationEvent> {  
  @Override  
  public void onApplicationEvent(AbstractAuthenticationEvent event) {  
    System.out.println("Received event of type:   
      "+event.getClass().getName()+": "+event.toString());  
  }  
}  

 

你会发现我们这里使用了@Component注解,但是我们也可以在XML配置文件中简单声明一个Spring bean。

 

记住,ApplicationListener的实现类必须注明对什么类型的事件感兴趣,在Spring 3中通过在ApplicationListener接口引用中声明泛型来标注。Spring的ApplicationEventMulticaster使用一些巧妙的方法来检查类的接口实现声明并确保正确的事件到达正确的类中。

 

【巧妙的注解。你如果对复杂的注解处理和运行时检查注解感到好奇,毫无疑问那你应该查看使用Spring的o.s.context.event.GenericApplicationListenerAdapter分发ApplicationEvent事件的巧妙代码。看一下并学习一些Java反射的新技巧。】

 

重启应用,然后进行一些常用的行为如登录、退出以及登录失败。你能看到,当这些行为执行时,适当的时间被触发并打印在控制台上。

 

尽管我们声明了自己的ApplicationListener来接受所有的认证事件,但是在大多数场景下这并不实用,根据系统使用情况的,在一个小时内可能会有数千个时间触发。通过修改类implements关键词上的泛型标示,我们能够使得实现类至监听一种类型的事件。

内置的ApplicationListeners

Spring Security提供了两个ApplicationListener的实现类,它们绑定了在Spring Security中使用的Apache Commons Logging日志。两个ApplicationListener实现类,一个是负责认证事件,一个负责授权时间。你可以像以下代码那样配置它们:

 

java代码:
<bean id="authenticationListener"   
  class="org.springframework.security .authentication.event.LoggerListener"/>  
<bean id="authorizationListener"   
  class="org.springframework.security .access.event.LoggerListener"/>  

 

这两个监听器将会输出Commons Logging日志以对应的类命名。一个示例记录AbstractAuthenticationFailureEvent大致如下:

 

java代码:
WARN - Authentication event   
AuthenticationFailureBadCredentialsEvent: adb; details: org.  
springframework.security.web.authentication.WebAuthenticationDetails@2  
55f8: RemoteIpAddress: 127.0.0.1; SessionId: B20510F25464B109CE3AE94D9  
FBF981E; exception: Bad credentials  

 

如果你要实现类似的ApplicationListener来记录有用的事件,这些类可以作为模板。

 

大量的应用事件

 

Spring Security提供了很多的事件,其试图在用户认证请求的所有点上给出有用的信息。你的应用可以监听可用的各种事件,这个范围可以很广泛(所有认证失败)也可以很窄小(一个用户通过提供完整的凭证认证成功)。完整的事件列表在附录:参考资料中。一些其它的关于异常处理和事件监听的注意事项如下:

 

    授权事件和框架抛出异常的匹配关系可以通过DefaultAuthenticationEventPublisher的exceptionMappings属性配置;

    记住,正如我们在本章前面看到的,跟踪HttpSession的生命周期是通过web.xml配置的变化,而不直接是Spring。

 

你可以看到Spring Security的异常和事件处理很强大,允许在你的安全系统中进行很多场景的跟踪和对活动的响应。

构建一个自定义实现的SpEL表达式处理器

我们将会阐述一个扩展基本SpEL表达式处理器的简单例子,提供一个表达式如果当前日期的分钟数为偶数将会允许访问。尽管这是一个很牵强的例子,但是它描述了实现自定义SpEL表达式方法的所有步骤。

 

让我们创建一个类com.packtpub.springsecurity.security.CustomWebSecurityExpressionRoot以建立自定义扩展的WebSecurityExpressionRoot。

 

java代码:
public class CustomWebSecurityExpressionRoot extends WebSecurityExpressionRoot {  
  public CustomWebSecurityExpressionRoot (Authentication a, FilterInvocation fi) {  
    super(a, fi);  
  }  
  public boolean isEvenMinute() {  
    return (Calendar.getInstance().get(Calendar.MINUTE) % 2) == 0;  
  }  
}  

 

接下里,我们需要一个实现WebSecurityExpressionHandler的类。我们扩展了DefaultWebSecurityExpressionHandler并重写一个方法在com.packtpub.springsecurity.security.CustomWebSecurityExpressionHandler类中建立自己的CustomWebSecurityExpressionRoot。

 

java代码:
public class CustomWebSecurityExpressionHandler   
  extends DefaultWebSecurityExpressionHandler {  
  public EvaluationContext createEvaluationContext(Authentication authentication, FilterInvocation fi) {  
    StandardEvaluationContext ctx = (StandardEvaluationContext)   
      super.createEvaluationContext(authentication, fi);  
    SecurityExpressionRoot root = new CustomWebSecurityExpressionRoot(authentication, fi);  
    ctx.setRootObject(root);  
      return ctx;  
  }  
} 

 

最后,当建立Voter时需要重新配置bean引用,如下:

 

java代码:
<bean class="com.packtpub.springsecurity.security.CustomWebSecurityExpressionHandler"   id="customExpressionHandler"/>  
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter"   id="expressionVoter">  
  <property name="expressionHandler" ref="customExpressionHandler"/>  
</bean> 

 

 

现在,我们可以使用这个表达式来根据时间的分钟数是偶数还是奇数进行限制访问。

 

java代码:
<security:intercept-url pattern="/*" access="evenMinute"/>  


 

 很显然,这是一个简单的例子,但是阐述了实现自定义SpEL属性的基本步骤,你可以使用这种方式来控制对应用特定部分的访问。

 

【配置自定义SpEL Voter的技术可能在使用security命名空间的时候也会用到,只需使用access-decision-manager-ref属性定义一个自定义的AccessDecisionManager,就像我们在第二章见过的那样。】

小结

在本章中,我们介绍了Spring Security标准配置的功能并实现了一些高级的自定义功能。我们涉及到以下的内容:

    实现自定义的servlet过滤器来处理基于IP和角色的过滤以及基于HTTP头的SSO请求;

    添加一个自定义的AuthenticationProvider及支持类,从而实现HTTP请求头的SSO;

    了解session固化防护和session并发处理的配置及好处,包括一些间接的功能以允许用户进行session报告;

    配置自定义的访问控制拒绝处理并了解何时及为何AccessDeniedException会被抛出,还有怎样适当地响应它;

    替换Spring Security的自动化配置为手动声明所有需要的参与类,这借助于标准的Sping bean XML配置技术;

    了解一些基于Spring bean配置的高级功能,包括session管理和事件发布;

    实现自定义和内置的ApplicationListener来响应Spring Security框架发布的特定事件;

    实现标准SpEL表达式处理器的自定义扩展以允许个性化的URL访问表达式。

 

多有趣的一章!我们已经很习惯Spring Security,并进行了一些高级的扩展和自定义。

 

在第七章中,我们将会进行高级配置的旅程,通过使用访问控制列表使得实现复杂认证变得可能。

 



感谢  iteye  lengyun3566 。

 

他的博客地址:http://lengyun3566.iteye.com

他的新浪微博:http://weibo.com/1920428940

本书源代码的地址:http://www.packtpub.com/support?nid=4435

精品视频课程推荐

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

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

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

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

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

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

评论(0)
请登录后评论 登录

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

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