- 浏览: 304864 次
文章分类
最新评论
-
流年末年:
那四个参数还是没看懂.....能不能解释下showPassst ...
我写的密码强度验证方法(原创) -
kingcs2008:
// 验证pws.jsshowPassstrength(&qu ...
我写的密码强度验证方法(原创) -
h957355152:
请问博主这个怎么用呢?我直接放到jsp里面调用showPass ...
我写的密码强度验证方法(原创) -
qq_15138059:
我写的全国省市县三级联动菜单,拿出来和大家分享了(原创) -
valenon:
评论呢?从MAIL FROM命令开始貌似就出错了:500 Er ...
如何发送伪造的电子邮件
认证事件处理
有一个重要的功能只能通过基于 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 的实现类,如下:
- < bean id = "defaultAuthEventPublisher"
- class = "org.springframework.security.authentication .DefaultAuthenticationEventPublisher" />
接下来,我们将会把它织入到使用的 AuthenticationManager 中:
- < 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 如下:
- 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 实现类,一个是负责认证事件,一个负责授权时间。你可以像以下代码那样配置它们:
- < bean id = "authenticationListener"
- class = "org.springframework.security .authentication.event.LoggerListener" />
- < bean id = "authorizationListener"
- class = "org.springframework.security .access.event.LoggerListener" />
这两个监听器将会输出 Commons Logging 日志以对应的类命名。一个示例记录 AbstractAuthenticationFailureEvent 大致如下:
- 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 提供了很多的事件,其试图在用户认证请求的所有点上给出有用的信息。你的应用可以监听可用的各种事件,这个范围可以很广泛(所有认证失败)也可以很窄小(一个用户通过提供完整的凭证认证成功)。完整的事件列表在附录:参考资料 中。一些其它的关于异常处理和事件监听的注意事项如下:
l 授权事件和框架抛出异常的匹配关系可以通过 DefaultAuthenticationEventPublisher 的 exceptionMappings 属性配置;
l 记住,正如我们在本章前面看到的,跟踪 HttpSession 的生命周期是通过 web.xml 配置的变化,而不直接是 Spring 。
你可以看到 Spring Security 的异常和事件处理很强大,允许在你的安全系统中进行很多场景的跟踪和对活动的响应。
构建一个自定义实现的SpEL 表达式处理器
我们将会阐述一个扩展基本 SpEL 表达式处理器的简单例子,提供一个表达式如果当前日期的分钟数为偶数将会允许访问。尽管这是一个很牵强的例子,但是它描述了实现自定义 SpEL 表达式方法的所有步骤。
让我们创建一个类 com.packtpub.springsecurity.security.CustomWebSecurityExpressionRoot 以建立自定义扩展的 WebSecurityExpressionRoot 。
- 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 。
- 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 引用,如下:
- < 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 >
现在,我们可以使用这个表达式来根据时间的分钟数是偶数还是奇数进行限制访问。
很显然,这是一个简单的例子,但是阐述了实现自定义 SpEL 属性的基本步骤,你可以使用这种方式来控制对应用特定部分的访问。
【配置自定义 SpEL Voter 的技术可能在使用 security 命名空间的时候也会用到,只需使用 access-decision-manager-ref 属性定义一个自定义的 AccessDecisionManager ,就像我们在第二章见过的那样。】
小结
在本章中,我们介绍了 Spring Security 标准配置的功能并实现了一些高级的自定义功能。我们涉及到以下的内容:
l 实现自定义的 servlet 过滤器来处理基于 IP 和角色的过滤以及基于 HTTP 头的 SSO 请求;
l 添加一个自定义的 AuthenticationProvider 及支持类,从而实现 HTTP 请求头的 SSO ;
l 了解 session 固化防护和 session 并发处理的配置及好处,包括一些间接的功能以允许用户进行 session 报告;
l 配置自定义的访问控制拒绝处理并了解何时及为何 AccessDeniedException 会被抛出,还有怎样适当地响应它;
l 替换 Spring Security 的自动化配置为手动声明所有需要的参与类,这借助于标准的 Sping bean XML 配置技术;
l 了解一些基于 Spring bean 配置的高级功能,包括 session 管理和事件发布;
l 实现自定义和内置的 ApplicationListener 来响应 Spring Security 框架发布的特定事件;
l 实现标准 SpEL 表达式处理器的自定义扩展以允许个性化的 URL 访问表达式。
多有趣的一章!我们已经很习惯 Spring Security ,并进行了一些高级的扩展和自定义。
在第七章中,我们将会进行高级配置的旅程,通过使用访问控制列表使得实现复杂认证变得可能。
发表评论
-
spring-security3 配置和使用(二)承上
2011-12-22 06:42 10442、xml配置,配置内容如下: Xml代码 ... -
spring-security3 配置和使用 (一)(转载)
2011-12-22 06:43 935最近项目中要使用到spring-security,可能研究 ... -
SpringSecurity3.X--一个简单实现(转载)
2011-12-22 06:43 2668作者对springsecurity研究不深,算是个初学者吧,最 ... -
SpringSecurity3.X--验证码(转载)
2011-12-22 06:44 1057一般来说,登录时都会要求用户输入验证码,以防止恶意登录。 可 ... -
SpringSecurity3.X--前台与后台登录认证(转载)
2011-12-23 06:33 3447不过一般我们在管理系统时都会分前台与后台,也就是说,前台与后台 ... -
SpringSecurity3.X--remember-me(转载)
2011-12-22 06:44 1740笔者在SpringSecurity中配置remember-me ... -
《Spring Security3》第六章第六部分翻译(Spring Security基于bean的高级配置)
2011-12-23 06:34 1053Spring Security 基于bean 的高级配 ... -
《Spring Security3》第六章第五部分翻译(手动配置Spring Security设施的bean)(转载)
2011-12-23 06:34 1008手动配置Spring Security 设施的be ... -
《Spring Security3》第六章第四部分翻译(异常处理)(转载)
2011-12-23 06:34 1235理解和配置异常处理 ... -
《Spring Security3》第六章第三部分翻译(Session的管理和并发)(转载)
2011-12-24 10:20 4227Session 的管理和并发 ... -
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)(转载)
2011-12-24 10:21 1513实现自定义的 AuthenticationProvide ... -
《Spring Security3》第六章第一部分翻译(自定义安全过滤器)(转载)
2011-12-24 10:21 1117第六章 高级配置和扩展 到目前为止,我 ... -
《Spring Security3》第五章第四部分翻译(方法安全的高级知识和小结)(转载)
2011-12-24 10:22 1051方法安全的高级知 ... -
《Spring Security3》第五章第三部分翻译(保护业务层)
2011-12-24 10:22 877保护业务层 到目前为止,在 ... -
《Spring Security3》第五章第二部分翻译下(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 1024使用控制器逻辑进行有条件渲染内容 ... -
《Spring Security3》第五章第二部分翻译上(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 958实现授权精确控制的方法 精确的授权指的是基于用 ... -
《Spring Security3》第五章第一部分翻译(重新思考应用功能和安全) (转载)
2011-12-25 00:47 948第五章 精确的 ... -
《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)(转载)
2011-12-25 00:47 1248将 Remember me 功能 ... -
《Spring Security3》第四章第三部分翻译下(密码加salt)(转载)
2011-12-25 00:48 1800你是否愿意在密码上添加点salt ? 如果安 ... -
《Spring Security3》第四章第三部分翻译上(配置安全的密码)(转载)
2011-12-26 00:41 1005配置安全的密码 我们 ...
相关推荐
第6章 Spring 2.x AOP和AspectJ支持 第二部分 基础主题 第7章 Spring对JDBC的支持 第8章 Spring中的事务管理 第9章 Spring对ORM的支持 第10章 Spring MVC框架 第11章 整合Spring...
第6章 Spring 2.x AOP和AspectJ支持 第二部分 基础主题 第7章 Spring对JDBC的支持 第8章 Spring中的事务管理 第9章 Spring对ORM的支持 第10章 Spring MVC框架 第11章 整合Spring...
第6章 Spring 2.x AOP和AspectJ支持 第二部分 基础主题 第7章 Spring对JDBC的支持 第8章 Spring中的事务管理 第9章 Spring对ORM的支持 第10章 Spring MVC框架 第11章 整合Spring与其他...
第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider Manager 7.2.2 根据数据库验证身份 7.2.3 根据LDAP仓库进行身份验证 7.3 控制访问 7.3.1 访问决策投票 7.3.2 决定如何投票...
第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2...
第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理...
第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2...
第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider Manager 7.2.2 根据数据库验证身份 7.2.3 根据LDAP仓库进行身份验证 7.3 控制访问 7.3.1 访问决策投票 7.3.2 决定如何投票...