再说springsecurity

来源:互联网 发布:mac book air 2016型号 编辑:程序博客网 时间:2024/05/01 23:08

    上次发过一个springsecurity的文章但都是比较简单的,角色,权限什么的都是配置在配置文件中的,在现实中不是很实用,这次就更深入的弹下springsecurity

 

1)登录部分

   在springsecurity中提供了各种的认证,表单认证,基本认证等,只要通过配置一下就可以实现你想要的认证方式.这里只说下表单验证

 

 login-page指的是你的登录页面.default-target-url是你登录以后成功的页面,always-use-default-target是你登录成功后后是不是始终跳转到default-target-url.因为有时候你想访问一个url,但因为没有权限而被弹到了都登录页面,你登录后想直接到你刚访问的页面的话,就需要把它设为false.

 

再来看下/lndex.action所对应的登录页面:

这个页面就要一个用户名的输入,一个密码的输入以及一个提交的按钮,只贴部分代码:

 

 

name的属性必须是j_username和j_password哦,提交的action名字是j_spring_security_check,然后springsecurity会帮你完成剩下的事情.当然你也可以自己定制,那么你就不能用springsecurity默认的过滤器链了,要自己改造下..

 

   当然这还没完,想下登录的过程,用户到登录页面--->到数据库中查看是否有此用户---->如果有,把这个用户的用户名阿,角色之类的保存到session中,一般都是这个做法.当然在这个过程中你可以加入自己的功能,比如你想在登录的时候把所有的资源权限都加载入内存,以提高效率....

 

  要用springsecurity从你的数据库中取得用户名密码,以及角色那么你要在后台做些改动.首先是数据库的设计,一般建个user表以及role表和他们的中间表.

 

  你的应用中应该要有个对应user的Javabean来模拟用户,这个javabean要实现UserDetails这个类:

   

public GrantedAuthority[] getAuthorities() 方法主要是把这个用户的角色都放到 GrantedAuthority的数组中返回.

 

你还需要实现UserDetailsService,以模拟用户的读出.

 

 

loadUserByUsername这个方法就是读取用户的过程了.最后在配置文件中

 

这样就可以实现正常的登录了.

这里有个值得借鉴的地方就是一般我们登录后会把登录的信息放在session中,而springsecurity是放在threadlocal中的,节约了session的空间.

 

2)权限部分

   权限部分指每个角色可以访问哪些Url,对某些资源可以有哪些操作.数据库中建个resource的表,维护各种需要认证才能访问的资源,比如url,数据什么的.简单的例子:

  

比如大部分的系统都会有个要求就是,用户登进来以后显示用户有权限看的那部分菜单.那么就可以在这张表中存入左右的菜单信息,再建个与role的中间表.维护哪些角色可以访问哪些url.

 

让我们再来想想资源的验证应该要包含哪些内容呢:

    1)首先,用户一登录看到各自权限可以看到的菜单,这个比较好实现.

    2)aop实现权限的验证,用户访问某个资源时,先看下数据库用户是否有这个资源的权限,没有就报个没有权限的错

    3)页面上实现权限的验证,用户没有权限则看不到按钮.

 

我们看下第2项在springsecurity中如何实现,先来配置文件:

 

我们实现的是 FilterSecurityInterceptor,实际上在过滤链中已经包含了springsecurity默认实现的FilterSecurityInterceptor,只不过我们要实现自己的验证机制,那么就重新实现了FilterSecurityInterceptor,然后通过<custom-filter after="LAST" />把它加入过滤链的尾端.

 

secureResourceFilterInvocationDefinitionSource是我们自己的实现,它需要实现FilterInvocationDefinitionSource接口,这个类主要是返回受保护的url:

 

 

注意getAttributes这个方法,他实际上就是根据请求的url然后到数据库去找这个url对应的role,如果找不到就返回空.

 

之后springsecurity会把这个方法返回的role列表和登录的用户属于的role做对比,决定用户是否有权限访问这个url

这样就实现的基本的权限控制,当然在springsecurity中你还可以实现对方法的保护.以及领域对象的保护(acl)

 

总的来说springsecurity的灵活性非常的强,基本可以满足所有对权限访问的需求.而且基于aop实现,你可以方便的在不同的项目中移植,但灵活性的代价就是学习springsecurity不是那么容易上手,需要一定时间才可以灵活的运用

 

推荐另一篇写的很好的关于springsecurity的文章http://www.javaeye.com/topic/319965