首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

Spring Security3.1例证

2014-01-15 
Spring Security3.1例子这几天学习了一下Spring Security3.1,从官网下载了Spring Security3.1版本进行练习

Spring Security3.1例子

这几天学习了一下Spring Security3.1,从官网下载了Spring Security3.1版本进行练习,经过多次尝试才摸清了其中的一些原理。本人不才,希望能帮助大家。还有,这次我第二次写博客啊,文体不是很行。希望能让观看者不产生疲惫的感觉,我已经心满意足了。

一、数据库结构

???? 先来看一下数据库结构,采用的是基于角色-资源-用户的权限管理设计。(MySql数据库)

??? 为了节省篇章,只对比较重要的字段进行注释。

??? 1.用户表Users

??? CREATE TABLE `users` (

????? ?-- 账号是否有限 1. 是 0.否
?????? `enable` int(11) default NULL,
?????? `password` varchar(255) default NULL,
? ???? `account` varchar(255) default NULL,
?????? `id` int(11) NOT NULL auto_increment,
?????? PRIMARY KEY? (`id`)
??? )

?

?? 2.角色表Roles

???CREATE TABLE `roles` (
???? `enable` int(11) default NULL,
???? `name` varchar(255) default NULL,
???? `id` int(11) NOT NULL auto_increment,
???? PRIMARY KEY? (`id`)
?? )

?

?? 3 用户_角色表users_roles

?? CREATE TABLE `users_roles` (

???? --用户表的外键
???? `uid` int(11) default NULL,

???? --角色表的外键
???? `rid` int(11) default NULL,
???? `urId` int(11) NOT NULL auto_increment,
???? PRIMARY KEY? (`urId`),
???? KEY `rid` (`rid`),
???? KEY `uid` (`uid`),
??? CONSTRAINT `users_roles_ibfk_1` FOREIGN KEY (`rid`) REFERENCES `roles` (`id`),
??? CONSTRAINT `users_roles_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `users` (`id`)
?? )

?

?? 4.资源表resources

???CREATE TABLE `resources` (
???? `memo` varchar(255) default NULL,

???? --?权限所对应的url地址
???? `url` varchar(255) default NULL,

???? --优先权
???? `priority` int(11) default NULL,

???? --类型
???? `type` int(11) default NULL,

???? --权限所对应的编码,例201代表发表文章
???? `name` varchar(255) default NULL,
???? `id` int(11) NOT NULL auto_increment,
???? PRIMARY KEY? (`id`)
?? )

?

?? 5.角色_资源表roles_resources

??? CREATE TABLE `roles_resources` (
????? `rsid` int(11) default NULL,
????? `rid` int(11) default NULL,
????? `rrId` int(11) NOT NULL auto_increment,
????? PRIMARY KEY? (`rrId`),
????? KEY `rid` (`rid`),
????? KEY `roles_resources_ibfk_2` (`rsid`),
????? CONSTRAINT `roles_resources_ibfk_2` FOREIGN KEY (`rsid`) REFERENCES `resources` (`id`),
????? CONSTRAINT `roles_resources_ibfk_1` FOREIGN KEY (`rid`) REFERENCES `roles` (`id`)
????? )

?

? 二、系统配置

?? 所需要的jar包,请自行到官网下载,我用的是Spring Security3.1.0.RC1版的。把dist下的除了源码件包导入就行了。还有那些零零碎的?? 数据库驱动啊,log4j.jar等等,我相信在用Spring Security之前,大家已经会的了。

? 1) web.xml

?

我们自定义的Filter必须在它之前,过滤客服请求。接下来看下我们最主要的myFilter吧。

?

3)myFilter

? (1) MySecurityFilter.java 过滤用户请求

?

[java] view plaincopy
  1. public?class?MySecurityFilter?extends?AbstractSecurityInterceptor?implements?Filter?{??????//与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,??
  2. ????//其他的两个组件,已经在AbstractSecurityInterceptor定义??????private?FilterInvocationSecurityMetadataSource?securityMetadataSource;??
  3. ??????@Override??
  4. ????public?SecurityMetadataSource?obtainSecurityMetadataSource()?{??????????return?this.securityMetadataSource;??
  5. ????}????
  6. ????public?void?doFilter(ServletRequest?request,?ServletResponse?response,??????????????FilterChain?chain)?throws?IOException,?ServletException?{??
  7. ????????FilterInvocation?fi?=?new?FilterInvocation(request,?response,?chain);??????????invoke(fi);??
  8. ????}????????
  9. ????private?void?invoke(FilterInvocation?fi)?throws?IOException,?ServletException?{??????????//?object为FilterInvocation对象??
  10. ??????????????????//super.beforeInvocation(fi);源码??????????//1.获取请求资源的权限??
  11. ????????//执行Collection<ConfigAttribute>?attributes?=?SecurityMetadataSource.getAttributes(object);??????????//2.是否拥有权限??
  12. ????????//this.accessDecisionManager.decide(authenticated,?object,?attributes);??????????InterceptorStatusToken?token?=?super.beforeInvocation(fi);??
  13. ????????try?{??????????????fi.getChain().doFilter(fi.getRequest(),?fi.getResponse());??
  14. ????????}?finally?{??????????????super.afterInvocation(token,?null);??
  15. ????????}??????}??
  16. ??????public?FilterInvocationSecurityMetadataSource?getSecurityMetadataSource()?{??
  17. ????????return?securityMetadataSource;??????}??
  18. ??????public?void?setSecurityMetadataSource(FilterInvocationSecurityMetadataSource?securityMetadataSource)?{??
  19. ????????this.securityMetadataSource?=?securityMetadataSource;??????}??
  20. ??????????public?void?init(FilterConfig?arg0)?throws?ServletException?{??
  21. ????????//?TODO?Auto-generated?method?stub??????}??
  22. ??????????public?void?destroy()?{??
  23. ????????//?TODO?Auto-generated?method?stub????????????
  24. ????}????
  25. ????@Override??????public?Class<??extends?Object>?getSecureObjectClass()?{??
  26. ????????//下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误??????????return?FilterInvocation.class;??
  27. ????}??}??

?

? 核心的InterceptorStatusToken token = super.beforeInvocation(fi);会调用我们定义的accessDecisionManager:decide(Object object)和securityMetadataSource

? :getAttributes(Object object)方法。

?

?(2)MySecurityMetadataSource.java

?

[java] view plaincopy
  1. //1?加载资源与权限的对应关系??public?class?MySecurityMetadataSource?implements?FilterInvocationSecurityMetadataSource?{??
  2. ????//由spring调用??????public?MySecurityMetadataSource(ResourcesDao?resourcesDao)?{??
  3. ????????this.resourcesDao?=?resourcesDao;??????????loadResourceDefine();??
  4. ????}????
  5. ????private?ResourcesDao?resourcesDao;??????private?static?Map<String,?Collection<ConfigAttribute>>?resourceMap?=?null;??
  6. ??????public?ResourcesDao?getResourcesDao()?{??
  7. ????????return?resourcesDao;??????}??
  8. ??????public?void?setResourcesDao(ResourcesDao?resourcesDao)?{??
  9. ????????this.resourcesDao?=?resourcesDao;??????}??
  10. ??????public?Collection<ConfigAttribute>?getAllConfigAttributes()?{??
  11. ????????//?TODO?Auto-generated?method?stub??????????return?null;??
  12. ????}????
  13. ????public?boolean?supports(Class<?>?clazz)?{??????????//?TODO?Auto-generated?method?stub??
  14. ????????return?true;??????}??
  15. ????//加载所有资源与权限的关系??????private?void?loadResourceDefine()?{??
  16. ????????if(resourceMap?==?null)?{??????????????resourceMap?=?new?HashMap<String,?Collection<ConfigAttribute>>();??
  17. ????????????List<Resources>?resources?=?this.resourcesDao.findAll();??????????????for?(Resources?resource?:?resources)?{??
  18. ????????????????Collection<ConfigAttribute>?configAttributes?=?new?ArrayList<ConfigAttribute>();??????????????????????????????????//以权限名封装为Spring的security?Object??
  19. ????????????????ConfigAttribute?configAttribute?=?new?SecurityConfig(resource.getName());??????????????????configAttributes.add(configAttribute);??
  20. ????????????????resourceMap.put(resource.getUrl(),?configAttributes);??????????????}??
  21. ????????}????????????
  22. ????????Set<Entry<String,?Collection<ConfigAttribute>>>?resourceSet?=?resourceMap.entrySet();??????????Iterator<Entry<String,?Collection<ConfigAttribute>>>?iterator?=?resourceSet.iterator();??
  23. ??????????????}??
  24. ????//返回所请求资源所需要的权限??????public?Collection<ConfigAttribute>?getAttributes(Object?object)?throws?IllegalArgumentException?{??
  25. ??????????????????String?requestUrl?=?((FilterInvocation)?object).getRequestUrl();??
  26. ????????System.out.println("requestUrl?is?"?+?requestUrl);??????????if(resourceMap?==?null)?{??
  27. ????????????loadResourceDefine();??????????}??
  28. ????????return?resourceMap.get(requestUrl);??????}??
  29. ??}??

?

?这里的resourcesDao,熟悉Dao设计模式和Spring 注入的朋友应该看得明白。

?

(3)MyUserDetailServiceImpl.java

?

[java] view plaincopy
  1. public?class?MyUserDetailServiceImpl?implements?UserDetailsService?{????????
  2. ????private?UsersDao?usersDao;??????public?UsersDao?getUsersDao()?{??
  3. ????????return?usersDao;??????}??
  4. ??????public?void?setUsersDao(UsersDao?usersDao)?{??
  5. ????????this.usersDao?=?usersDao;??????}??
  6. ??????????public?UserDetails?loadUserByUsername(String?username)?throws?UsernameNotFoundException?{??
  7. ????????System.out.println("username?is?"?+?username);??????????Users?users?=?this.usersDao.findByName(username);??
  8. ????????if(users?==?null)?{??????????????throw?new?UsernameNotFoundException(username);??
  9. ????????}??????????Collection<GrantedAuthority>?grantedAuths?=?obtionGrantedAuthorities(users);??
  10. ??????????????????boolean?enables?=?true;??
  11. ????????boolean?accountNonExpired?=?true;??????????boolean?credentialsNonExpired?=?true;??
  12. ????????boolean?accountNonLocked?=?true;????????????
  13. ????????User?userdetail?=?new?User(users.getAccount(),?users.getPassword(),?enables,?accountNonExpired,?credentialsNonExpired,?accountNonLocked,?grantedAuths);??????????return?userdetail;??
  14. ????}????????
  15. ????//取得用户的权限??????private?Set<GrantedAuthority>?obtionGrantedAuthorities(Users?user)?{??
  16. ????????Set<GrantedAuthority>?authSet?=?new?HashSet<GrantedAuthority>();??????????Set<Roles>?roles?=?user.getRoles();??
  17. ??????????????????for(Roles?role?:?roles)?{??
  18. ????????????Set<Resources>?tempRes?=?role.getResources();??????????????for(Resources?res?:?tempRes)?{??
  19. ????????????????authSet.add(new?GrantedAuthorityImpl(res.getName()));??s???????????}??
  20. ????????}??????????return?authSet;??
  21. ????}??}??

?

?

(4) MyAccessDecisionManager.java

[java] view plaincopy
  1. public?class?MyAccessDecisionManager?implements?AccessDecisionManager?{????????
  2. ????public?void?decide(Authentication?authentication,?Object?object,?Collection<ConfigAttribute>?configAttributes)?throws?AccessDeniedException,?InsufficientAuthenticationException?{??????????if(configAttributes?==?null)?{??
  3. ????????????return;??????????}??
  4. ????????//所请求的资源拥有的权限(一个资源对多个权限)??????????Iterator<ConfigAttribute>?iterator?=?configAttributes.iterator();??
  5. ????????while(iterator.hasNext())?{??????????????ConfigAttribute?configAttribute?=?iterator.next();??
  6. ????????????//访问所请求资源所需要的权限??????????????String?needPermission?=?configAttribute.getAttribute();??
  7. ????????????System.out.println("needPermission?is?"?+?needPermission);??????????????//用户所拥有的权限authentication??
  8. ????????????for(GrantedAuthority?ga?:?authentication.getAuthorities())?{??????????????????if(needPermission.equals(ga.getAuthority()))?{??
  9. ????????????????????return;??????????????????}??
  10. ????????????}??????????}??
  11. ????????//没有权限??????????throw?new?AccessDeniedException("?没有权限访问!?");??
  12. ????}????
  13. ????public?boolean?supports(ConfigAttribute?attribute)?{??????????//?TODO?Auto-generated?method?stub??
  14. ????????return?true;??????}??
  15. ??????public?boolean?supports(Class<?>?clazz)?{??
  16. ????????//?TODO?Auto-generated?method?stub??????????return?true;??
  17. ????}????????
  18. }??

?

?

三、流程

?1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)
?2)用户发出请求
?3)过滤器拦截(MySecurityFilter:doFilter)
?4)取得请求资源所需权限(MySecurityMetadataSource:getAttributes)
?5)匹配用户拥有权限和请求权限(MyAccessDecisionManager:decide),如果用户没有相应的权限,

?????执行第6步,否则执行第7步。
?6)登录
?7)验证并授权(MyUserDetailServiceImpl:loadUserByUsername)
?8)重复4,5

?

热点排行