整合Spring Security自定义登录的简便方法

安全开源框架这块咱们基本上没什么选择,Spring Security是最常用的了,虽然它功能强大,但是还是过于复杂了。虽然3.0提供了auto config,但本质上它的复杂度没有降低,只是简化了一下配置而已。我始终认为它应该弄一个简化版,不要集成那么多的认证支撑,让人一看就懂的那种,个人意见哈。

 

我们最常用的基于用户名和密码的认证,SS提供了UsernamePasswordAuthenticationFilter,要求我们通过POST提交j_username/j_password两个参数来完成这个认证。这个设计真是相当别扭,从它的前身Acegi开始就这样了,这不符合我们最常用的开发需求,例如我们通常会加入一个验证码什么的。

 

网上有两种集成方案:

1. 自己实现一个验证码的Filter插入到UsernamePasswordAuthenticationFilter前面。

2. 重写一个UsernamePasswordAuthenticationFilter,加入验证码验证,修改配置替换原来的Filter。

 

虽然比较符合SS的扩展模式,但个人感觉还是太麻烦了。

 

我想了两种比较简单的方案,思路是这样的:

1. 先自己处理验证码,然后将请求转发给UsernamePasswordAuthenticationFilter进行登录。

2. 自己处理登录过程,登录表单则可以完全自己定义了。

 

第一种方案

仍要保持j_username和j_password两个参数名不变,因为SS没提供该参数名的可配置项。以Struts为例子来讲,首先表单提交到我们自定义的Action方法中,这时我们可以处理验证码。验证码验证通过后,将请求转发到 /j_spring_security_check即UsernamePasswordAuthenticationFilter。这里必须是RequestDispatcher的forward方式转发,因为这样才能将j_username和j_password参数带过去。

另外我们需要在web.xml中将SS的DelegatingFilterProxy配置为支持forward转发拦截的,因为默认配置只支持request拦截。

就这样,你想在验证用户之前干点啥都可以,自己在Action中处理吧。没有侵入性,就是参数名有点受限制。

 

第二种方案

SS的基本原理是在ThreadLocal线程变量中存入一个SecurityContext对象,在web中通过Filter不断的传递这个线程变量,使得web的一个线程范围内的程序都可以访问到这个SecurityContext对象。这个SecurityContext对象中存有一个Authentication对象,身份和权限都在这个Authentication对象中。第二种方案就是绕开SS的Filter手动的完成验证并设置Authentication对象。关键代码如下:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password);
Authentication authentication = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);

 authenticationManager是SS内置的一个组件,你需要定义一个别名进行注入引用。authenticationManager.authenticate(token)方法会抛出异常,你可以捕获处理这些异常,例如用户名密码错误、用户被禁用等等。在这种方案下你爱怎么自定义登录过程都可以了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值