首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Spring Security3.1 最新配备实例 (转载)

2012-11-11 
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

    ?

    四、结束语

    好了,终于写完了,回头看了一下,感觉不是怎么行。等我弄明白Spring Security它的原理之后,再回头修改下注释吧。大家觉得不妥的地方,可以留言,我会回复大家的。

    ?

热点排行