Spring security控制权限的几种方法

使用springSecurity3的四种方法概述

那么在Spring Security3的使用中,有4种方法:

一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证;

二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。

三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
目前这种方式已经实现,并经过验证。

四是修改spring security的源代码,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService两个类。
前者是将配置文件或数据库中存储的资源(url)提取出来加工成为url和权限列表的Map供Security使用,后者提取用户名和权限组成一个完整的 (UserDetails)User对象,该对象可以提供用户的详细信息供AuthentationManager进行认证与授权使用。
该方法理论上可行,但是比较暴力,也没有时间实现,未验证,以后再研究。

说明一下,我目前调通的环境为: java1.6 + struts2.1.6 + spring3.0.1 + hibernate3.3.1 + spring security3.0.2 + oracle9i + weblogic10.3,
顺便提一下,目前(2011-4-2)serutity的最新版本为3.1,比较稳定的版本为3.0.5和2.0.6。

当然在进行spring security3的下面4种方法介绍之前,先假定SSH2的环境已经配置完毕,进入正常开发的过程,并且已经导入
spring security3.0.2的5个jar包,分别为:
spring-security-acl-3.0.2.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-taglibs-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
当然还有其他相关的jar包,在此不再赘述。


第一种方法

第一种方法比较简单,可参考Spring Security自带的例子spring-security-samples-tutorial-3.0.2.RELEASE。
这里给出下载网址:http://www.springsource.com/download/community?sid=1087087,不过在下载之前必须填写相应的用户信息,才允许下载。各种版本号的均可以下载。

在spring-security-samples-tutorial-3.0.2.RELEASE的例子里,硬编码的配置请参见applicationContext-security.xml文件中的内容。
里面配置了用户名、经过MD5加密后的密码密文、相关的权限,以及与权相对应的访问资源(URL)。还有对于Session超时时的处理。
特别是因为版本号为3.0.2,因此还增加了对表达式的配置演示,具体内容请参见该例子。

当然你最好运行起该例子来,感受一下,你可以直接将下载下来的解压缩后的文件夹中找到spring-security-samples- tutorial-3.0.2.RELEASE.war文件,然后拷贝到Tomcat的安装目录下的\webapps文件夹下,然后运行Tomcat的服 务器,服务器在启动过程中,会自动解开该war文件,在IE内输入http://localhost:8080/webapps/spring-security-samples-tutorial-3.0.2.RELEASE就可以运行该系统了。在此不再赘述。

第二种方法

第二种方法的代码如下:

使用到的两个表,用户表和权限表的SQL语句。将用户和权限以数据库进行存储。

[sql] view plain copy
  1. createtableUSERS(
  2. USERNAMEVARCHAR2(50)notnull,
  3. PASSWORDVARCHAR2(50)notnull,
  4. ENABLEDNUMBER(1)notnull,
  5. USERNAMECNVARCHAR2(50),
  6. primarykey(username)
  7. )
  8. createtableAUTHORITIES(
  9. USERNAMEVARCHAR2(50)notnull,
  10. AUTHORITYVARCHAR2(50)notnull
  11. )

-- 外键使用户和权限相联。

[sql] view plain copy
  1. Create/Recreateprimary,uniqueandforeignkeyconstraints
  2. altertableAUTHORITIES
  3. addconstraintFK_AUTHORITIES_USERSforeignkey(USERNAME)
  4. referencesUSERS(USERNAME);


可插入几条数据做为试验,首先插入用户:

[sql] view plain copy
  1. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  2. values('lxb','c7d3f4c857bc8c145d6e5d40c1bf23d9',1,'登录用户','AAAHmhAALAAAAAOAAA');
  3. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  4. values('admin','ceb4f32325eda6142bd65215f4c0f371',1,'系统管理员','AAAHmhAALAAAAAPAAA');
  5. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  6. values('user','47a733d60998c719cf3526ae7d106d13',1,'普通用户','AAAHmhAALAAAAAPAAB');

再插入角色:

[sql] view plain copy
  1. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  2. values('admin','ROLE_PLATFORMADMIN','AAAHmjAALAAAAAgAAA');
  3. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  4. values('admin','ROLE_SYSADMIN','AAAHmjAALAAAAAgAAB');
  5. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  6. values('lxb','ROLE_LOGIN','AAAHmjAALAAAAAeAAA');
  7. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  8. values('lxb','ROLE_LOGINTOWELCOME','AAAHmjAALAAAAAeAAB');
  9. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  10. values('user','ROLE_USER','AAAHmjAALAAAAAgAAC');

第二种方法之密码加密

可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过MD5进行加密过的,并且以用户名做为了盐值,最后就成为32位数字这个 样子,这个你可以参见下面applicationContext-Security.xml中的password-encoder和salt- source的配置就会明白。
那么在spring security3中是如何加密的呢?当我们设置了pawwrod-encoder和salt-source之后,Spring Security3会根据配置,采用相匹配的加密算法(比如设置了MD5加密算法)再加上salt-source进行加密,形成32位数字的密文。
比如用户名为yew,密码为yew1234,盐值为用户名yew。那么最后加密的明文为“yew1234{yew}”,密文就为“8fe2657d1599dba8e78a7a0bda8651bb”。

我们在试验过程中,通常喜欢先将几个常用的用户及密码插入数据库进行试验,这种情况下如何得到该用户的密码密文呢?
不妨试试我这个办法,假设,用户名为user,密码明文为user369,而且在配置文件里面设置了以MD5作为加密算法,并以用户名做为盐值。
那么你可以首先将各个信息组合成待加密的密码明文, 应是 密码明文 + { + 盐值 + }, 那么很明显,上述user的密码明文应当是:

user369{user}

拿上述的字串拷贝到http://www.51240.com/md5jiami/网页上的输入框里,点击加密按钮,下面即可生成32位数字的密码密文。

哈哈,屡试不爽啊。这个方法要谨慎使用,一般人我不告诉他。


第二种方法之相关配置

将权限及资源(URL或Action)的关系配置在xml文件中,并且配置与Spring Security3相关的其他配置:

1、applicationContext-Security.xml代码

[html] view plain copy
  1. <b:beansxmlns="http://www.springframework.org/schema/security"
  2. xmlns:b="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beans
  4. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  5. http://www.springframework.org/schema/security
  6. http://www.springframework.org/schema/security/spring-security-3.0.xsd">
  7. <httpauto-config="true"access-denied-page="/accessDenied.jsp">
  8. <intercept-urlpattern="/**/*.jpg"filters="none"/>
  9. <intercept-urlpattern="/**/*.png"filters="none"/>
  10. <intercept-urlpattern="/**/*.gif"filters="none"/>
  11. <intercept-urlpattern="/**/*.css"filters="none"/>
  12. <intercept-urlpattern="/**/*.js"filters="none"/>
  13. <intercept-urlpattern="/login.jsp"filters="none"/>
  14. <intercept-urlpattern="/jsp/forgotpassword.jsp"filters="none"/>
  15. <remember-medata-source-ref="dataSource"/>
  16. <session-managementinvalid-session-url="/sessionTimeout.jsp"/>
  17. http>
  18. <authentication-manageralias="authenticationManager">
  19. <authentication-provideruser-service-ref="userDetailsManager">
  20. <password-encoderref="passwordEncoder">
  21. <salt-sourceuser-property="username"/>
  22. password-encoder>
  23. authentication-provider>
  24. authentication-manager>
  25. b:beans>

2、applicationContext.service.xml:

[html] view plain copy
  1. <beansxmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:util="http://www.springframework.org/schema/util"
  4. xmlns:jee="http://www.springframework.org/schema/jee"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xmlns:context="http://www.springframework.org/schema/context"
  8. xsi:schemaLocation="http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10. http://www.springframework.org/schema/aop
  11. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  12. http://www.springframework.org/schema/tx
  13. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  14. http://www.springframework.org/schema/jee
  15. http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
  16. http://www.springframework.org/schema/context
  17. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  18. http://www.springframework.org/schema/util
  19. http://www.springframework.org/schema/util/spring-util-3.0.xsd">
  20. <beanid="messageSource"
  21. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  22. <propertyname="basename"
  23. value="classpath:org/springframework/security/messages_zh_CN"/>
  24. bean>
  25. <beanid="passwordEncoder"
  26. class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
  27. <beanid="userDetailsManager"
  28. class="org.springframework.security.provisioning.JdbcUserDetailsManager">
  29. <propertyname="dataSource"ref="dataSource"/>
  30. <propertyname="userCache"ref="userCache"/>
  31. bean>
  32. <beanid="userCache"
  33. class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
  34. <propertyname="cache"ref="userEhCache"/>
  35. bean>
  36. <beanid="userEhCache"class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  37. <propertyname="cacheName"value="userCache"/>
  38. <propertyname="cacheManager"ref="cacheManager"/>
  39. bean>
  40. <beanid="cacheManager"
  41. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
  42. <beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
  43. <propertyname="dataSource"ref="dataSource"/>
  44. bean>
  45. beans>



3、web.xml:

[html] view plain copy
  1. <web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  4. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  5. <context-param>
  6. <param-name>webAppRootKeyparam-name>
  7. <param-value>log.rootparam-value>
  8. context-param>
  9. <context-param>
  10. <param-name>log4jConfigLocationparam-name>
  11. <param-value>classpath:/log4j.propertiesparam-value>
  12. context-param>
  13. <context-param>
  14. <param-name>log4jRefreshIntervalparam-name>
  15. <param-value>60000param-value>
  16. context-param>
  17. <listener>
  18. <listener-class>org.springframework.web.util.Log4jConfigListenerlistener-class>
  19. listener>
  20. <listener>
  21. <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  22. listener>
  23. <filter>
  24. <filter-name>characterEncodingFilterfilter-name>
  25. <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
  26. <init-param>
  27. <param-name>encodingparam-name>
  28. <param-value>gbkparam-value>
  29. init-param>
  30. <init-param>
  31. <param-name>ForceEncodingparam-name>
  32. <param-value>trueparam-value>
  33. init-param>
  34. filter>
  35. <filter-mapping>
  36. <filter-name>characterEncodingFilterfilter-name>
  37. <url-pattern>/*url-pattern>
  38. filter-mapping>
  39. <filter>
  40. <filter-name>springSecurityFilterChainfilter-name>
  41. <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
  42. filter>
  43. <filter-mapping>
  44. <filter-name>springSecurityFilterChainfilter-name>
  45. <url-pattern>/*url-pattern>
  46. filter-mapping>
  47. <filter>
  48. <filter-name>struts2filter-name>
  49. <filter-class>
  50. org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  51. filter-class>
  52. filter>
  53. <filter-mapping>
  54. <filter-name>struts2filter-name>
  55. <url-pattern>/*url-pattern>
  56. filter-mapping>
  57. <filter>
  58. <filter-name>struts-cleanupfilter-name>
  59. <filter-class>
  60. org.apache.struts2.dispatcher.ActionContextCleanUp
  61. filter-class>
  62. filter>
  63. <filter-mapping>
  64. <filter-name>struts-cleanupfilter-name>
  65. <url-pattern>/*url-pattern>
  66. filter-mapping>
  67. <listener>
  68. <listener-class>
  69. org.springframework.web.util.IntrospectorCleanupListener
  70. listener-class>
  71. listener>
  72. <session-config>
  73. <session-timeout>20session-timeout>
  74. session-config>
  75. <welcome-file-list>
  76. <welcome-file>login.jspwelcome-file>
  77. welcome-file-list>
  78. web-app>
令人欣喜的是,整个Security配置过程中,除了建立数据库和编写配置文件之外,不需要编写任何的代码。怎么样? 有点意思吧!

第二种方法中遇见的问题

当然,首次使用Spring serutiry,在整合的过程中,我还是遇见了不少问题,当然有些问题比如找不到类呀,包呀,和框架的整合呀等问题不作为谈论的重点。主要还是探讨Spring Security的配置和注意事项的问题。

我在其中碰到的对我印象最深的问题是,当完全配置好之后,重启Web服务器,却发现Spring Security不能拦截任何的URL了,这使我感到惊诧,因为在去年时,我已经将该框架搭建完成,在当时正是使用的该种方法,并且在试验是否能够拦截 jsp文件时进行了确认是没有问题的。

接下来我又整理了一下applicationContext-security.xml的文件才发现, 除了不需要进行检测的图片及登录页面之外,没有对任何的资源和权限之间的对应关系进行配置,参见下面的代码:

[html] view plain copy
  1. <httpauto-config="true"access-denied-page="/accessDenied.jsp">
  2. <intercept-urlpattern="/**/*.jpg"filters="none"/>
  3. <intercept-urlpattern="/**/*.png"filters="none"/>
  4. <intercept-urlpattern="/**/*.gif"filters="none"/>
  5. <intercept-urlpattern="/**/*.css"filters="none"/>
  6. <intercept-urlpattern="/**/*.js"filters="none"/>
  7. <intercept-urlpattern="/login.jsp"filters="none"/>
  8. <intercept-urlpattern="/jsp/forgotpassword.jsp"filters="none"/>
  9. <remember-medata-source-ref="dataSource"/>
  10. <session-managementinvalid-session-url="/sessionTimeout.jsp"/>
  11. http>

这样一来,spring security3就会认为根本不需要对任何的URL或Action进行检测(注意上面代码中被注释掉的4条配置)。 哈哈,当时这个问题深深动摇了我对Spring security的信心,花费了这么多天的精力,却是这样的结果,当时就在考虑是否有更好的替代品。有点崩溃啊。 还好,深深地求知欲和征服欲让我坚持下来了。
哈哈,这算不算Spring Security的一个Bug呢?没有任何的权限与资源的配置,就认为登录后的用户具有访问任何资源的权限,说起来有点可怕哈。

当然,当我将上述代码中被注释的4条配置放开后,Spring security奇迹般的恢复了活力。

接下来实现了jsp型URL的拦截之后,我又遇见了不能拦截action的情况,不过经过多次的配置和重启服务试验,终于发现,在配置 Action与权限时,一定要在Action的路径前面加“/”斜杠,否则,Spring Security就会对该请求的URL熟视无睹,无视它的存在,即使你在Action的前后加上*号进行匹配也不会起任何作用,哈哈,不禁慨叹 Spring Security的牛脾气。


第二种方法BTW

顺便提一下子,Spring Security3需要配置的过滤器是双重的,首先在web.xml中配置一个过滤器代理,参见上述web.xml中的springSecurityFilterChain配置。
我们通常设置过滤的url模式为/*,就是说任何的url访问都要进行过滤,工作量有点大哈。当然我们可以为之设置不同的过滤url模式,比 如.action、.do、.jsp等。这样的话,遇到.action或.jsp或.do结尾的url访问,Spring Security就会突然站出来打截,若是其他的访问,Spring Security就会挥一挥手,潇洒地让你路过。
所以说,这个过滤器主要对大的方面进行拦截,一些细小的活儿,还是要交给第二重过滤器。 就是说,这第一重过滤器是个总代理,他威武地管理着一个过滤器链。

那么这第二重过滤器的配置,就是那些所谓的过滤器链,分别包括“记住我”、“登录”、“注销”、“url访问”等的过滤器,这个过滤器依顺 序排开,形成一个过滤链条。具体拦截我们明细Url的是一个叫做FilterInterCeptor的伙计,我认为这个家伙是在整个过滤器链条中是最重要 的一个,因为我们登录系统之后,要访问的任何资源都必须经得他的同意。 那么这第二重链条就设置在applicationContext-security.xml文件中的元素下面。
什么,你看不到? 忘记告诉你了,从spring security2开始,就使用了命名空间,若你在中设置了auto="true",Spring Security就会在服务启动时自动加载
所有的过滤器链,省事了吧!

第三种方法

当然,spring security3毕竟是西方国家的东西,以英文为主,使用习惯和文化的差异共存,况且为了适应大多数Web应用的权限管理,作者将Spring Security3打造的精简而灵活。精简指Spring Security3对用户和权限的表设计的非常简单,并且没有采用数据库来管理资源(URL)。这样的话,对于我们国人用户来说,是个很大的遗憾,这个遗 憾甚至能够影响到我们对安全框架的选型。你想啊,在国内大多数项目中,均设置了比较复杂的权限控制,一般就会涉及到用户、角色、权限、资源4张表,若要加 上4张表之间的对应关系表3张,得有7张表才行。

得7张表才行,但是Spring Security3才给我们提供了2张最简洁的表,这足以不能完成国人用户的项目应用。那么在对Spring Security3一无所知的情况下,
我们很容易就会放弃对该安全框架的选型。

还好,Spring Security3提供了灵活的扩展方法。具体应该扩展哪些类呢? 或者到底Spring Security3工作的流程如何,你不妨参看下面一篇文章,就会获得
一些启示,网址为:http://www.blogjava.net/youxia/archive/2008/12/07/244883.html, 哈哈,谢谢分享。

还有一个地址很有价值,http://wenku.baidu.com/view/4ec7e324ccbff121dd368364.html,我就参考着上面的介绍扩展了4个类。

不过我得提一下,原文的作者为了考验你的耐性和自信心,故意在代码里面卖了几点小小的关子,因此若是完全按照作者的原文代码装配起来的权限 系统,是不会那么顺利地工作的,天下似乎真是没有不花费力气的午餐!在装配完成后,我也是经过九九八十一难的折磨,在用户、角色、权限、资源的
“天下黄河九曲十八弯”里面盘旋迂回,终于到达了成功的彼岸。至此才对Spring Security有了更深层次的理解,更加佩服作者的良苦用心。 哈哈。

并扩展了User类以增加其相关的各类其他信息(如Email,职务,所在单位id等)。


相关的代码如下(包含5个关键类):

[java] view plain copy
  1. /*
  2. *@(#)MyFilterSecurityInterceptor.java2011-3-23上午07:53:03
  3. *
  4. *Copyright2011bySparta
  5. */
  6. packageavatar.base.security;
  7. importjava.io.IOException;
  8. importjavax.servlet.Filter;
  9. importjavax.servlet.FilterChain;
  10. importjavax.servlet.FilterConfig;
  11. importjavax.servlet.ServletException;
  12. importjavax.servlet.ServletRequest;
  13. importjavax.servlet.ServletResponse;
  14. importorg.springframework.security.access.SecurityMetadataSource;
  15. importorg.springframework.security.access.intercept.AbstractSecurityInterceptor;
  16. importorg.springframework.security.access.intercept.InterceptorStatusToken;
  17. importorg.springframework.security.web.FilterInvocation;
  18. importorg.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
  19. /***//**
  20. *该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。
  21. *securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。
  22. *该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中,
  23. *供SpringSecurity使用,用于权限校验。
  24. *@authorsparta11/3/29
  25. *
  26. */
  27. publicclassMyFilterSecurityInterceptor
  28. extendsAbstractSecurityInterceptor
  29. implementsFilter{
  30. privateFilterInvocationSecurityMetadataSourcesecurityMetadataSource;
  31. publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)
  32. throwsIOException,ServletException{
  33. FilterInvocationfi=newFilterInvocation(request,response,chain);
  34. invoke(fi);
  35. }
  36. publicFilterInvocationSecurityMetadataSourcegetSecurityMetadataSource(){
  37. returnthis.securityMetadataSource;
  38. }
  39. publicClassextendsObject>getSecureObjectClass(){
  40. returnFilterInvocation.class;
  41. }
  42. publicvoidinvoke(FilterInvocationfi)throwsIOException,ServletException{
  43. InterceptorStatusTokentoken=super.beforeInvocation(fi);
  44. try{
  45. fi.getChain().doFilter(fi.getRequest(),fi.getResponse());
  46. }finally{
  47. super.afterInvocation(token,null);
  48. }
  49. }
  50. @Override
  51. publicSecurityMetadataSourceobtainSecurityMetadataSource(){
  52. returnthis.securityMetadataSource;
  53. }
  54. publicvoidsetSecurityMetadataSource(FilterInvocationSecurityMetadataSourcesecurityMetadataSource){
  55. this.securityMetadataSource=securityMetadataSource;
  56. }
  57. publicvoiddestroy(){
  58. }
  59. publicvoidinit(FilterConfigfilterconfig)throwsServletException{
  60. }
  61. }
  62. /**//*
  63. *@(#)MyInvocationSecurityMetadataSourceService.java2011-3-23下午02:58:29
  64. *
  65. *Copyright2011bySparta
  66. */
  67. packageavatar.base.security;
  68. importjava.util.ArrayList;
  69. importjava.util.Collection;
  70. importjava.util.HashMap;
  71. importjava.util.Iterator;
  72. importjava.util.List;
  73. importjava.util.Map;
  74. importorg.hibernate.Session;
  75. importorg.hibernate.SessionFactory;
  76. importorg.springframework.beans.factory.annotation.Autowired;
  77. importorg.springframework.context.ApplicationContext;
  78. importorg.springframework.context.support.ClassPathXmlApplicationContext;
  79. importorg.springframework.security.access.ConfigAttribute;
  80. importorg.springframework.security.access.SecurityConfig;
  81. importorg.springframework.security.core.GrantedAuthority;
  82. importorg.springframework.security.core.context.SecurityContextHolder;
  83. importorg.springframework.security.core.userdetails.UserDetails;
  84. importorg.springframework.security.web.FilterInvocation;
  85. importorg.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
  86. importorg.springframework.security.web.util.AntUrlPathMatcher;
  87. importorg.springframework.security.web.util.UrlMatcher;
  88. importorg.springframework.stereotype.Service;
  89. importavatar.base.security.dao.PubAuthoritiesResourcesHome;
  90. /***//**
  91. *最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。此类在初始化时,应该取到所有资源及其对应角色的定义。
  92. *
  93. */
  94. @Service
  95. publicclassMyInvocationSecurityMetadataSourceServiceimplements
  96. FilterInvocationSecurityMetadataSource{
  97. @Autowired
  98. privatePubAuthoritiesResourcesHomepubAuthoritiesResourcesHome;
  99. privateUrlMatcherurlMatcher=newAntUrlPathMatcher();
  100. privatestaticMap>resourceMap=null;
  101. publicMyInvocationSecurityMetadataSourceService(){
  102. loadResourceDefine();
  103. }
  104. privatevoidloadResourceDefine(){
  105. ApplicationContextcontext=newClassPathXmlApplicationContext(
  106. "classpath:applicationContext.xml");
  107. SessionFactorysessionFactory=(SessionFactory)context
  108. .getBean("sessionFactory");
  109. Sessionsession=sessionFactory.openSession();
  110. Stringusername="";
  111. Stringsql="";
  112. //在Web服务器启动时,提取系统中的所有权限。
  113. sql="selectauthority_namefrompub_authorities";
  114. Listquery=session.createSQLQuery(sql).list();
  115. /**//*
  116. *应当是资源为key,权限为value。资源通常为url,权限就是那些以ROLE_为前缀的角色。一个资源可以由多个权限来访问。
  117. *sparta
  118. */
  119. resourceMap=newHashMap>();
  120. for(Stringauth:query){
  121. ConfigAttributeca=newSecurityConfig(auth);
  122. Listquery1=session
  123. .createSQLQuery(
  124. "selectb.resource_string"
  125. +"fromPub_Authorities_Resourcesa,Pub_Resourcesb,"
  126. +"Pub_authoritiescwherea.resource_id=b.resource_id"
  127. +"anda.authority_id=c.authority_idandc.Authority_name='"
  128. +auth+"'").list();
  129. for(Stringres:query1){
  130. Stringurl=res;
  131. /**//*
  132. *判断资源文件和权限的对应关系,如果已经存在相关的资源url,则要通过该url为key提取出权限集合,将权限增加到权限集合中。
  133. *sparta
  134. */
  135. if(resourceMap.containsKey(url)){
  136. Collectionvalue=resourceMap.get(url);
  137. value.add(ca);
  138. resourceMap.put(url,value);
  139. }else{
  140. Collectionatts=newArrayList();
  141. atts.add(ca);
  142. resourceMap.put(url,atts);
  143. }
  144. }
  145. }
  146. }
  147. @Override
  148. publicCollectiongetAllConfigAttributes(){
  149. returnnull;
  150. }
  151. //根据URL,找到相关的权限配置。
  152. @Override
  153. publicCollectiongetAttributes(Objectobject)
  154. throwsIllegalArgumentException{
  155. //object是一个URL,被用户请求的url。
  156. Stringurl=((FilterInvocation)object).getRequestUrl();
  157. intfirstQuestionMarkIndex=url.indexOf("?");
  158. if(firstQuestionMarkIndex!=-1){
  159. url=url.substring(0,firstQuestionMarkIndex);
  160. }
  161. Iteratorite=resourceMap.keySet().iterator();
  162. while(ite.hasNext()){
  163. StringresURL=ite.next();
  164. if(urlMatcher.pathMatchesUrl(url,resURL)){
  165. returnresourceMap.get(resURL);
  166. }
  167. }
  168. returnnull;
  169. }
  170. @Override
  171. publicbooleansupports(Classarg0){
  172. returntrue;
  173. }
  174. }
  175. /**//*
  176. *@(#)MyUserDetailsService.java2011-3-23上午09:04:31
  177. *
  178. *Copyright2011bySparta
  179. */
  180. packageavatar.base.security;
  181. importjava.util.ArrayList;
  182. importjava.util.Collection;
  183. importjavax.sql.DataSource;
  184. importorg.springframework.beans.factory.annotation.Autowired;
  185. importorg.springframework.dao.DataAccessException;
  186. importorg.springframework.security.core.GrantedAuthority;
  187. importorg.springframework.security.core.userdetails.User;
  188. importorg.springframework.security.core.userdetails.UserCache;
  189. importorg.springframework.security.core.userdetails.UserDetails;
  190. importorg.springframework.security.core.userdetails.UserDetailsService;
  191. importorg.springframework.security.core.userdetails.UsernameNotFoundException;
  192. importorg.springframework.stereotype.Service;
  193. importavatar.base.security.dao.PubAuthoritiesResourcesHome;
  194. importavatar.base.security.dao.PubUsersHome;
  195. /***//**
  196. *该类的主要作用是为SpringSecurity提供一个经过用户认证后的UserDetails。
  197. *该UserDetails包括用户名、密码、是否可用、是否过期等信息。
  198. *sparta11/3/29
  199. */
  200. @Service
  201. publicclassMyUserDetailsServiceimplementsUserDetailsService{
  202. @Autowired
  203. privatePubUsersHomepubUsersHome;
  204. @Autowired
  205. privatePubAuthoritiesResourcesHomepubAuthoritiesResourcesHome;
  206. @Autowired
  207. privateDataSourcedataSource;
  208. @Autowired
  209. privateUserCacheuserCache;
  210. @Override
  211. publicUserDetailsloadUserByUsername(Stringusername)
  212. throwsUsernameNotFoundException,DataAccessException{
  213. Collectionauths=newArrayList();
  214. //得到用户的权限
  215. auths=pubUsersHome.loadUserAuthoritiesByName(username);
  216. Stringpassword=null;
  217. //取得用户的密码
  218. password=pubUsersHome.getPasswordByUsername(username);
  219. returnnewUser(username,password,true,"",true,true,true,auths);
  220. }
  221. //setPubUsersHome
  222. publicvoidsetPubUsersHome(PubUsersHomepubUsersHome){
  223. this.pubUsersHome=pubUsersHome;
  224. }
  225. publicPubUsersHomegetPubUsersHome(){
  226. returnpubUsersHome;
  227. }
  228. //setPubAuthoritiesResourcesHome
  229. publicvoidsetPubAuthoritiesResourcesHome(PubAuthoritiesResourcesHomepubAuthoritiesResourcesHome){
  230. this.pubAuthoritiesResourcesHome=pubAuthoritiesResourcesHome;
  231. }
  232. publicPubAuthoritiesResourcesHomegetPubAuthoritiesResourcesHome(){
  233. returnpubAuthoritiesResourcesHome;
  234. }
  235. //setDataSource
  236. publicvoidsetDataSource(DataSourcedataSource){
  237. this.dataSource=dataSource;
  238. }
  239. publicDataSourcegetDataSource(){
  240. returndataSource;
  241. }
  242. //设置用户缓存功能。
  243. publicvoidsetUserCache(UserCacheuserCache){
  244. this.userCache=userCache;
  245. }
  246. publicUserCachegetUserCache(){
  247. returnthis.userCache;
  248. }
  249. }
  250. /**//*
  251. *@(#)MyAccessDecisionManager.java2011-3-23下午04:41:12
  252. *
  253. *Copyright2011bySparta
  254. */
  255. packageavatar.base.security;
  256. importjava.util.Collection;
  257. importjava.util.Iterator;
  258. importorg.springframework.security.access.AccessDecisionManager;
  259. importorg.springframework.security.access.AccessDeniedException;
  260. importorg.springframework.security.access.ConfigAttribute;
  261. importorg.springframework.security.access.SecurityConfig;
  262. importorg.springframework.security.authentication.InsufficientAuthenticationException;
  263. importorg.springframework.security.core.Authentication;
  264. importorg.springframework.security.core.GrantedAuthority;
  265. /***//**
  266. *AccessdecisionManager在Springsecurity中是很重要的。
  267. *
  268. *在验证部分简略提过了,所有的Authentication实现需要保存在一个GrantedAuthority对象数组中。
  269. *这就是赋予给主体的权限。GrantedAuthority对象通过AuthenticationManager
  270. *保存到Authentication对象里,然后从AccessDecisionManager读出来,进行授权判断。
  271. *
  272. *SpringSecurity提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。
  273. *一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。
  274. *这个AccessDecisionManager被AbstractSecurityInterceptor调用,
  275. *它用来作最终访问控制的决定。这个AccessDecisionManager接口包含三个方法:
  276. *
  277. voiddecide(Authenticationauthentication,ObjectsecureObject,
  278. Listconfig)throwsAccessDeniedException;
  279. booleansupports(ConfigAttributeattribute);
  280. booleansupports(Classclazz);
  281. 从第一个方法可以看出来,AccessDecisionManager使用方法参数传递所有信息,这好像在认证评估时进行决定。
  282. 特别是,在真实的安全方法期望调用的时候,传递安全Object启用那些参数。
  283. 比如,让我们假设安全对象是一个MethodInvocation。
  284. 很容易为任何Customer参数查询MethodInvocation,
  285. 然后在AccessDecisionManager里实现一些有序的安全逻辑,来确认主体是否允许在那个客户上操作。
  286. 如果访问被拒绝,实现将抛出一个AccessDeniedException异常。
  287. 这个supports(ConfigAttribute)方法在启动的时候被
  288. AbstractSecurityInterceptor调用,来决定AccessDecisionManager
  289. 是否可以执行传递ConfigAttribute。
  290. supports(Class)方法被安全拦截器实现调用,
  291. 包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。
  292. */
  293. publicclassMyAccessDecisionManagerimplementsAccessDecisionManager{
  294. publicvoiddecide(Authenticationauthentication,Objectobject,
  295. CollectionconfigAttributes)
  296. throwsAccessDeniedException,InsufficientAuthenticationException{
  297. if(configAttributes==null){
  298. return;
  299. }
  300. Iteratorite=configAttributes.iterator();
  301. while(ite.hasNext()){
  302. ConfigAttributeca=ite.next();
  303. StringneedRole=((SecurityConfig)ca).getAttribute();
  304. //ga为用户所被赋予的权限。needRole为访问相应的资源应该具有的权限。
  305. for(GrantedAuthorityga:authentication.getAuthorities()){
  306. if(needRole.trim().equals(ga.getAuthority().trim())){
  307. return;
  308. }
  309. }
  310. }
  311. thrownewAccessDeniedException("");
  312. }
  313. publicbooleansupports(ConfigAttributeattribute){
  314. returntrue;
  315. }
  316. publicbooleansupports(Classclazz){
  317. returntrue;
  318. }
  319. }

数据库的SQL及预置数据:

[sql] view plain copy
  1. promptPL/SQLDeveloperimportfile
  2. promptCreatedon2011年6月1日byAdministrator
  3. setfeedbackoff
  4. setdefineoff
  5. promptCreatingSYS_AUTHORITIES
  6. createtableSYS_AUTHORITIES
  7. (
  8. AUTHORITY_IDVARCHAR2(32)notnull,
  9. AUTHORITY_NAMEVARCHAR2(40),
  10. AUTHORITY_DESCVARCHAR2(100),
  11. ENABLEDNUMBER(1),
  12. ISSYSNUMBER(1),
  13. MODULEVARCHAR2(4)
  14. )
  15. tablespaceSCJD
  16. pctfree10
  17. initrans1
  18. maxtrans255
  19. storage
  20. (
  21. initial64K
  22. minextents1
  23. maxextentsunlimited
  24. );
  25. commentontableSYS_AUTHORITIES
  26. is'权限表';
  27. commentoncolumnSYS_AUTHORITIES.MODULE
  28. is'所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。';
  29. altertableSYS_AUTHORITIES
  30. addconstraintPK_PUB_AUTHORITIESprimarykey(AUTHORITY_ID)
  31. usingindex
  32. tablespaceSCJD
  33. pctfree10
  34. initrans2
  35. maxtrans255
  36. storage
  37. (
  38. initial64K
  39. minextents1
  40. maxextentsunlimited
  41. );
  42. promptCreatingSYS_RESOURCES
  43. createtableSYS_RESOURCES
  44. (
  45. RESOURCE_IDVARCHAR2(32)notnull,
  46. RESOURCE_NAMEVARCHAR2(100),
  47. RESOURCE_DESCVARCHAR2(100),
  48. RESOURCE_TYPEVARCHAR2(40),
  49. RESOURCE_STRINGVARCHAR2(200),
  50. PRIORITYNUMBER(1),
  51. ENABLEDNUMBER(1),
  52. ISSYSNUMBER(1),
  53. MODULEVARCHAR2(4)
  54. )
  55. tablespaceSCJD
  56. pctfree10
  57. initrans1
  58. maxtrans255
  59. storage
  60. (
  61. initial64K
  62. minextents1
  63. maxextentsunlimited
  64. );
  65. commentontableSYS_RESOURCES
  66. is'资源表';
  67. commentoncolumnSYS_RESOURCES.PRIORITY
  68. is'(暂不用,保留)';
  69. commentoncolumnSYS_RESOURCES.MODULE
  70. is'所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。(暂不用,保留)';
  71. altertableSYS_RESOURCES
  72. addconstraintPK_PUB_RESOURCESprimarykey(RESOURCE_ID)
  73. usingindex
  74. tablespaceSCJD
  75. pctfree10
  76. initrans2
  77. maxtrans255
  78. storage
  79. (
  80. initial64K
  81. minextents1
  82. maxextentsunlimited
  83. );
  84. promptCreatingSYS_AUTHORITIES_RESOURCES
  85. createtableSYS_AUTHORITIES_RESOURCES
  86. (
  87. IDNUMBER(13)notnull,
  88. AUTHORITY_IDVARCHAR2(32),
  89. RESOURCE_IDVARCHAR2(32),
  90. ENABLEDNUMBER(1)
  91. )
  92. tablespaceSCJD
  93. pctfree10
  94. initrans1
  95. maxtrans255
  96. storage
  97. (
  98. initial64K
  99. minextents1
  100. maxextentsunlimited
  101. );
  102. commentontableSYS_AUTHORITIES_RESOURCES
  103. is'权限资源表';
  104. altertableSYS_AUTHORITIES_RESOURCES
  105. addconstraintPK_PUB_AUTHORITIES_REprimarykey(ID)
  106. usingindex
  107. tablespaceSCJD
  108. pctfree10
  109. initrans2
  110. maxtrans255
  111. storage
  112. (
  113. initial64K
  114. minextents1
  115. maxextentsunlimited
  116. );
  117. altertableSYS_AUTHORITIES_RESOURCES
  118. addconstraintFK_PUB_AUTHORITIES_RE_AUforeignkey(AUTHORITY_ID)
  119. referencesSYS_AUTHORITIES(AUTHORITY_ID);
  120. altertableSYS_AUTHORITIES_RESOURCES
  121. addconstraintFK_PUB_AUTHORITIES_RE_REforeignkey(RESOURCE_ID)
  122. referencesSYS_RESOURCES(RESOURCE_ID);
  123. promptCreatingSYS_ROLES
  124. createtableSYS_ROLES
  125. (
  126. ROLE_IDVARCHAR2(32)notnull,
  127. ROLE_NAMEVARCHAR2(40),
  128. ROLE_DESCVARCHAR2(100),
  129. ENABLEDNUMBER(1),
  130. ISSYSNUMBER(1),
  131. MODULEVARCHAR2(4)
  132. )
  133. tablespaceSCJD
  134. pctfree10
  135. initrans1
  136. maxtrans255
  137. storage
  138. (
  139. initial64K
  140. minextents1
  141. maxextentsunlimited
  142. );
  143. commentontableSYS_ROLES
  144. is'角色表';
  145. commentoncolumnSYS_ROLES.MODULE
  146. is'所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。';
  147. altertableSYS_ROLES
  148. addconstraintPK_PUB_ROLESprimarykey(ROLE_ID)
  149. usingindex
  150. tablespaceSCJD
  151. pctfree10
  152. initrans2
  153. maxtrans255
  154. storage
  155. (
  156. initial64K
  157. minextents1
  158. maxextentsunlimited
  159. );
  160. promptCreatingSYS_ROLES_AUTHORITIES
  161. createtableSYS_ROLES_AUTHORITIES
  162. (
  163. IDNUMBER(13)notnull,
  164. ROLE_IDVARCHAR2(32),
  165. AUTHORITY_IDVARCHAR2(32),
  166. ENABLEDNUMBER(1)
  167. )
  168. tablespaceSCJD
  169. pctfree10
  170. initrans1
  171. maxtrans255
  172. storage
  173. (
  174. initial64K
  175. minextents1
  176. maxextentsunlimited
  177. );
  178. commentontableSYS_ROLES_AUTHORITIES
  179. is'角色权限表';
  180. altertableSYS_ROLES_AUTHORITIES
  181. addconstraintPK_PUB_ROLES_AUTHORITYprimarykey(ID)
  182. usingindex
  183. tablespaceSCJD
  184. pctfree10
  185. initrans2
  186. maxtrans255
  187. storage
  188. (
  189. initial64K
  190. minextents1
  191. maxextentsunlimited
  192. );
  193. altertableSYS_ROLES_AUTHORITIES
  194. addconstraintFK_PUB_ROLES_AUTHORITIES_AUforeignkey(AUTHORITY_ID)
  195. referencesSYS_AUTHORITIES(AUTHORITY_ID);
  196. altertableSYS_ROLES_AUTHORITIES
  197. addconstraintFK_PUB_ROLES_AUTHORITIES_ROLESforeignkey(ROLE_ID)
  198. referencesSYS_ROLES(ROLE_ID);
  199. promptCreatingSYS_USERS
  200. createtableSYS_USERS
  201. (
  202. USER_IDVARCHAR2(32)notnull,
  203. USER_ACCOUNTVARCHAR2(30),
  204. USER_NAMEVARCHAR2(40),
  205. USER_PASSWORDVARCHAR2(100),
  206. USER_DESCVARCHAR2(100),
  207. ENABLEDNUMBER(1),
  208. ISSYSNUMBER(1),
  209. USER_DEPTVARCHAR2(20),
  210. USER_DUTYVARCHAR2(10),
  211. SUB_SYSTEMVARCHAR2(30)
  212. )
  213. tablespaceSCJD
  214. pctfree10
  215. initrans1
  216. maxtrans255
  217. storage
  218. (
  219. initial64K
  220. minextents1
  221. maxextentsunlimited
  222. );
  223. commentontableSYS_USERS
  224. is'用户表';
  225. commentoncolumnSYS_USERS.USER_PASSWORD
  226. is'该密码是经加盐值加密的,格式为password{username}。比如用户的密码为user,用户名为user,那么通过MD5进行加密的串为:user{user}';
  227. commentoncolumnSYS_USERS.ISSYS
  228. is'是否是超级用户';
  229. commentoncolumnSYS_USERS.USER_DEPT
  230. is'所在单位';
  231. commentoncolumnSYS_USERS.USER_DUTY
  232. is'经理或主任';
  233. commentoncolumnSYS_USERS.SUB_SYSTEM
  234. is'该用户所负责的各子系统,可多个,中间用逗号分隔。(目前暂未用,作为保留字段)';
  235. altertableSYS_USERS
  236. addconstraintPK_PUB_USERSprimarykey(USER_ID)
  237. usingindex
  238. tablespaceSCJD
  239. pctfree10
  240. initrans2
  241. maxtrans255
  242. storage
  243. (
  244. initial64K
  245. minextents1
  246. maxextentsunlimited
  247. );
  248. promptCreatingSYS_USERS_ROLES
  249. createtableSYS_USERS_ROLES
  250. (
  251. IDNUMBER(13)notnull,
  252. USER_IDVARCHAR2(32),
  253. ROLE_IDVARCHAR2(32),
  254. ENABLEDNUMBER(1)
  255. )
  256. tablespaceSCJD
  257. pctfree10
  258. initrans1
  259. maxtrans255
  260. storage
  261. (
  262. initial64K
  263. minextents1
  264. maxextentsunlimited
  265. );
  266. commentontableSYS_USERS_ROLES
  267. is'用户角色表';
  268. altertableSYS_USERS_ROLES
  269. addconstraintPK_PUB_USERS_ROLESprimarykey(ID)
  270. usingindex
  271. tablespaceSCJD
  272. pctfree10
  273. initrans2
  274. maxtrans255
  275. storage
  276. (
  277. initial64K
  278. minextents1
  279. maxextentsunlimited
  280. );
  281. altertableSYS_USERS_ROLES
  282. addconstraintFK_USERS_ROLES_ROLESforeignkey(ROLE_ID)
  283. referencesSYS_ROLES(ROLE_ID);
  284. altertableSYS_USERS_ROLES
  285. addconstraintFK_USERS_ROLES_USERSforeignkey(USER_ID)
  286. referencesSYS_USERS(USER_ID);
  287. promptDisablingtriggersforSYS_AUTHORITIES
  288. altertableSYS_AUTHORITIESdisablealltriggers;
  289. promptDisablingtriggersforSYS_RESOURCES
  290. altertableSYS_RESOURCESdisablealltriggers;
  291. promptDisablingtriggersforSYS_AUTHORITIES_RESOURCES
  292. altertableSYS_AUTHORITIES_RESOURCESdisablealltriggers;
  293. promptDisablingtriggersforSYS_ROLES
  294. altertableSYS_ROLESdisablealltriggers;
  295. promptDisablingtriggersforSYS_ROLES_AUTHORITIES
  296. altertableSYS_ROLES_AUTHORITIESdisablealltriggers;
  297. promptDisablingtriggersforSYS_USERS
  298. altertableSYS_USERSdisablealltriggers;
  299. promptDisablingtriggersforSYS_USERS_ROLES
  300. altertableSYS_USERS_ROLESdisablealltriggers;
  301. promptDisablingforeignkeyconstraintsforSYS_AUTHORITIES_RESOURCES
  302. altertableSYS_AUTHORITIES_RESOURCESdisableconstraintFK_PUB_AUTHORITIES_RE_AU;
  303. altertableSYS_AUTHORITIES_RESOURCESdisableconstraintFK_PUB_AUTHORITIES_RE_RE;
  304. promptDisablingforeignkeyconstraintsforSYS_ROLES_AUTHORITIES
  305. altertableSYS_ROLES_AUTHORITIESdisableconstraintFK_PUB_ROLES_AUTHORITIES_AU;
  306. altertableSYS_ROLES_AUTHORITIESdisableconstraintFK_PUB_ROLES_AUTHORITIES_ROLES;
  307. promptDisablingforeignkeyconstraintsforSYS_USERS_ROLES
  308. altertableSYS_USERS_ROLESdisableconstraintFK_USERS_ROLES_ROLES;
  309. altertableSYS_USERS_ROLESdisableconstraintFK_USERS_ROLES_USERS;
  310. promptDeletingSYS_USERS_ROLES
  311. deletefromSYS_USERS_ROLES;
  312. commit;
  313. promptDeletingSYS_USERS
  314. deletefromSYS_USERS;
  315. commit;
  316. promptDeletingSYS_ROLES_AUTHORITIES
  317. deletefromSYS_ROLES_AUTHORITIES;
  318. commit;
  319. promptDeletingSYS_ROLES
  320. deletefromSYS_ROLES;
  321. commit;
  322. promptDeletingSYS_AUTHORITIES_RESOURCES
  323. deletefromSYS_AUTHORITIES_RESOURCES;
  324. commit;
  325. promptDeletingSYS_RESOURCES
  326. deletefromSYS_RESOURCES;
  327. commit;
  328. promptDeletingSYS_AUTHORITIES
  329. deletefromSYS_AUTHORITIES;
  330. commit;
  331. promptLoadingSYS_AUTHORITIES
  332. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  333. values('1303910437484','AUTH_xxx','xxx',null,null,'01');
  334. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  335. values('AUTH_LOGIN4','AUTH_LOGIN','登录',1,0,'01');
  336. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  337. values('AUTH_AFTERLOGINWELCOME5','AUTH_AFTERLOGINWELCOME','登录后欢迎界面',1,0,'01');
  338. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  339. values('AUTH_XTSZ_DEPT1','AUTH_XTSZ_DEPT','单位设置',1,0,'01');
  340. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  341. values('AUTH_XTSZ_USER2','AUTH_XTSZ_USER','用户设置、横向查询',1,0,'01');
  342. insertintoSYS_AUTHORITIES(AUTHORITY_ID,AUTHORITY_NAME,AUTHORITY_DESC,ENABLED,ISSYS,MODULE)
  343. values('AUTH_NODE_MGR3','AUTH_NODE_MGR','节点管理、纵向查询',1,0,'01');
  344. commit;
  345. prompt6recordsloaded
  346. promptLoadingSYS_RESOURCES
  347. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  348. values('1303909883031','ff','ff','action','b.jsp',null,1,0,null);
  349. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  350. values('1303909847687','ff1','ff1','action','b.jsp',null,1,0,null);
  351. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  352. values('node_mgr3','node_mgr','节点管理','url','/*/*/Tree.jsp',null,1,0,null);
  353. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  354. values('login4','login','登录','url','/login.jsp',null,1,0,null);
  355. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  356. values('index5','index','登录后欢迎页面','url','/index.jsp',null,1,0,null);
  357. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  358. values('resources_mgr','resources_mgr','资源管理','action','/managerResource',null,1,0,null);
  359. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  360. values('horizontal_qry6','horizontal_qry','横向查询','action','/horizontalQuery',null,1,0,null);
  361. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  362. values('vertical_qry7','vertical_qry','纵向查询','action','/verticalQuery',null,1,0,null);
  363. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  364. values('dep_mgr1','dep_mgr','单位管理','action','/UnitsManager',null,1,0,null);
  365. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  366. values('user_mgr2','user_mgr','用户管理','action','/managerUser',null,1,0,null);
  367. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  368. values('authority_mgr','authority_mgr','权限管理','action','/managerAuthority',null,1,0,null);
  369. insertintoSYS_RESOURCES(RESOURCE_ID,RESOURCE_NAME,RESOURCE_DESC,RESOURCE_TYPE,RESOURCE_STRING,PRIORITY,ENABLED,ISSYS,MODULE)
  370. values('role_mgr','role_mgr','角色管理','action','/managerRole',null,null,null,null);
  371. commit;
  372. prompt12recordsloaded
  373. promptLoadingSYS_AUTHORITIES_RESOURCES
  374. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  375. values(1,'AUTH_AFTERLOGINWELCOME5','index5',1);
  376. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  377. values(2,'AUTH_LOGIN4','login4',1);
  378. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  379. values(3,'AUTH_NODE_MGR3','node_mgr3',1);
  380. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  381. values(4,'AUTH_XTSZ_DEPT1','dep_mgr1',1);
  382. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  383. values(5,'AUTH_XTSZ_USER2','user_mgr2',1);
  384. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  385. values(7,'AUTH_XTSZ_USER2','horizontal_qry6',1);
  386. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  387. values(8,'AUTH_XTSZ_DEPT1','vertical_qry7',1);
  388. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  389. values(12,'AUTH_XTSZ_USER2','role_mgr',1);
  390. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  391. values(10,'AUTH_XTSZ_USER2','resources_mgr',1);
  392. insertintoSYS_AUTHORITIES_RESOURCES(ID,AUTHORITY_ID,RESOURCE_ID,ENABLED)
  393. values(11,'AUTH_XTSZ_USER2','authority_mgr',1);
  394. commit;
  395. prompt10recordsloaded
  396. promptLoadingSYS_ROLES
  397. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  398. values('1303463518765','ROLE_dd1','dd1',1,0,'01');
  399. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  400. values('1303463949640','ROLE_rr1','rr1',1,0,'02');
  401. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  402. values('ROLE_PLATFORMADMIN1','ROLE_PLATFORMADMIN','可管理整个平台的用户、单位设置。',1,1,'01');
  403. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  404. values('ROLE_USER2','ROLE_USER','普通用户',1,0,'01');
  405. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  406. values('ROLE_LOGINTOWELCOME4','ROLE_LOGINTOWELCOME','仅登录到欢迎界面!',1,0,'01');
  407. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  408. values('ROLE_SYSADMIN3','ROLE_SYSADMIN','可管理本系统的用户、单位设置。',1,0,'01');
  409. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  410. values('ROLE_WORK','ROLE_WORK','作业子系统的角色(试验)',1,0,'02');
  411. insertintoSYS_ROLES(ROLE_ID,ROLE_NAME,ROLE_DESC,ENABLED,ISSYS,MODULE)
  412. values('ROLE_LOGIN','ROLE_LOGIN','系统登录',1,0,'01');
  413. commit;
  414. prompt8recordsloaded
  415. promptLoadingSYS_ROLES_AUTHORITIES
  416. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  417. values(1,'ROLE_LOGINTOWELCOME4','AUTH_AFTERLOGINWELCOME5',1);
  418. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  419. values(2,'ROLE_PLATFORMADMIN1','AUTH_AFTERLOGINWELCOME5',1);
  420. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  421. values(3,'ROLE_PLATFORMADMIN1','AUTH_LOGIN4',1);
  422. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  423. values(4,'ROLE_PLATFORMADMIN1','AUTH_NODE_MGR3',1);
  424. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  425. values(5,'ROLE_PLATFORMADMIN1','AUTH_XTSZ_DEPT1',1);
  426. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  427. values(6,'ROLE_PLATFORMADMIN1','AUTH_XTSZ_USER2',1);
  428. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  429. values(7,'ROLE_SYSADMIN3','AUTH_XTSZ_DEPT1',1);
  430. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  431. values(8,'ROLE_SYSADMIN3','AUTH_XTSZ_USER2',1);
  432. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  433. values(9,'ROLE_USER2','AUTH_LOGIN4',1);
  434. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  435. values(10,'ROLE_LOGINTOWELCOME4','AUTH_LOGIN4',1);
  436. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  437. values(11,'ROLE_USER2','AUTH_AFTERLOGINWELCOME5',1);
  438. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  439. values(1303463962718,'1303463949640','AUTH_LOGIN4',1);
  440. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  441. values(1303463972234,'ROLE_WORK','AUTH_LOGIN4',1);
  442. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  443. values(1303463972235,'ROLE_WORK','AUTH_AFTERLOGINWELCOME5',1);
  444. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  445. values(1303463972250,'ROLE_WORK','AUTH_XTSZ_DEPT1',1);
  446. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  447. values(1303463972251,'ROLE_WORK','AUTH_XTSZ_USER2',1);
  448. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  449. values(1303463972265,'ROLE_WORK','AUTH_NODE_MGR3',1);
  450. insertintoSYS_ROLES_AUTHORITIES(ID,ROLE_ID,AUTHORITY_ID,ENABLED)
  451. values(1303287600015,'ROLE_LOGIN','AUTH_LOGIN4',1);
  452. commit;
  453. prompt18recordsloaded
  454. promptLoadingSYS_USERS
  455. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  456. values('1304494573750','lxb','lxb','c7d3f4c857bc8c145d6e5d40c1bf23d9',null,1,0,'10011001',null,'01');
  457. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  458. values('1304490737406','lxb','lxb','c7d3f4c857bc8c145d6e5d40c1bf23d9',null,1,0,'10011001',null,'01');
  459. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  460. values('1304574079546','ddd','ddd','0a4f6a961276619f7f91356bcba5a746',null,0,0,null,null,'01');
  461. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  462. values('1304573363921','lxb','卢小兵','09eb37d219cfa835db40e5ab587f7082','普通仅登录到欢迎界面!',0,0,'1001',null,'01');
  463. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  464. values('1304573484515','lll','lll','47acedc22cef8c3762c21a435e262d67',null,1,0,'1001',null,'01');
  465. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  466. values('admin1','admin','系统管理员','ceb4f32325eda6142bd65215f4c0f371','超级系统管理员',1,1,'1001',null,'01');
  467. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  468. values('user2','user','普通用户','47a733d60998c719cf3526ae7d106d13','普通用户',1,0,'1001',null,'01');
  469. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  470. values('sysUser3','sysUser','系统设置维护','8f0295328c34f8eedc2362e9f4a10b7e','系统设置用户',1,0,'1001',null,'01');
  471. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  472. values('lxb4','lxb','卢小兵','c7d3f4c857bc8c145d6e5d40c1bf23d9','普通仅登录到欢迎界面!',1,0,'1001',null,'01');
  473. insertintoSYS_USERS(USER_ID,USER_ACCOUNT,USER_NAME,USER_PASSWORD,USER_DESC,ENABLED,ISSYS,USER_DEPT,USER_DUTY,SUB_SYSTEM)
  474. values('1304566319625','lxb5','lx5','1abe40ed6d0da1c834586e8ecef61fe7',null,0,0,'10011001',null,'01');
  475. commit;
  476. prompt10recordsloaded
  477. promptLoadingSYS_USERS_ROLES
  478. insertintoSYS_USERS_ROLES(ID,USER_ID,ROLE_ID,ENABLED)
  479. values(1,'admin1','ROLE_PLATFORMADMIN1',1);
  480. insertintoSYS_USERS_ROLES(ID,USER_ID,ROLE_ID,ENABLED)
  481. values(2,'sysUser3','ROLE_SYSADMIN3',1);
  482. insertintoSYS_USERS_ROLES(ID,USER_ID,ROLE_ID,ENABLED)
  483. values(3,'user2','ROLE_USER2',1);
  484. insertintoSYS_USERS_ROLES(ID,USER_ID,ROLE_ID,ENABLED)
  485. values(4,'lxb4','ROLE_LOGINTOWELCOME4',1);
  486. insertintoSYS_USERS_ROLES(ID,USER_ID,ROLE_ID,ENABLED)
  487. values(5,'1304573484515','1303463518765',null);
  488. commit;
  489. prompt5recordsloaded
  490. promptEnablingforeignkeyconstraintsforSYS_AUTHORITIES_RESOURCES
  491. altertableSYS_AUTHORITIES_RESOURCESenableconstraintFK_PUB_AUTHORITIES_RE_AU;
  492. altertableSYS_AUTHORITIES_RESOURCESenableconstraintFK_PUB_AUTHORITIES_RE_RE;
  493. promptEnablingforeignkeyconstraintsforSYS_ROLES_AUTHORITIES
  494. altertableSYS_ROLES_AUTHORITIESenableconstraintFK_PUB_ROLES_AUTHORITIES_AU;
  495. altertableSYS_ROLES_AUTHORITIESenableconstraintFK_PUB_ROLES_AUTHORITIES_ROLES;
  496. promptEnablingforeignkeyconstraintsforSYS_USERS_ROLES
  497. altertableSYS_USERS_ROLESenableconstraintFK_USERS_ROLES_ROLES;
  498. altertableSYS_USERS_ROLESenableconstraintFK_USERS_ROLES_USERS;
  499. promptEnablingtriggersforSYS_AUTHORITIES
  500. altertableSYS_AUTHORITIESenablealltriggers;
  501. promptEnablingtriggersforSYS_RESOURCES
  502. altertableSYS_RESOURCESenablealltriggers;
  503. promptEnablingtriggersforSYS_AUTHORITIES_RESOURCES
  504. altertableSYS_AUTHORITIES_RESOURCESenablealltriggers;
  505. promptEnablingtriggersforSYS_ROLES
  506. altertableSYS_ROLESenablealltriggers;
  507. promptEnablingtriggersforSYS_ROLES_AUTHORITIES
  508. altertableSYS_ROLES_AUTHORITIESenablealltriggers;
  509. promptEnablingtriggersforSYS_USERS
  510. altertableSYS_USERSenablealltriggers;
  511. promptEnablingtriggersforSYS_USERS_ROLES
  512. altertableSYS_USERS_ROLESenablealltriggers;
  513. setfeedbackon
  514. setdefineon
  515. promptDone.

相关配置文件:

web.xml与第一种方法同。

applicationContext-security.xml:

[html] view plain copy
  1. xmlversion="1.0"encoding="UTF-8"?>
  2. <b:beansxmlns="http://www.springframework.org/schema/security"
  3. xmlns:b="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. http://www.springframework.org/schema/security
  7. http://www.springframework.org/schema/security/spring-security-3.0.xsd">
  8. <httpauto-config="true"access-denied-page="/accessDenied.jsp">
  9. <intercept-urlpattern="/**/*.jpg"filters="none"/>
  10. <intercept-urlpattern="/**/*.png"filters="none"/>
  11. <intercept-urlpattern="/**/*.gif"filters="none"/>
  12. <intercept-urlpattern="/**/*.css"filters="none"/>
  13. <intercept-urlpattern="/**/*.js"filters="none"/>
  14. <intercept-urlpattern="/login.jsp"filters="none"/>
  15. <intercept-urlpattern="/jsp/forgotpassword.jsp"
  16. filters="none"/>
  17. <form-loginlogin-page="/login.jsp"
  18. authentication-failure-url="/login.jsp?error=true"
  19. default-target-url="/index.jsp"/>
  20. <remember-medata-source-ref="dataSource"/>
  21. <session-managementinvalid-session-url="/sessionTimeout.jsp"/>
  22. <authentication-manageralias="authenticationManager">
  23. <authentication-provideruser-service-ref="userDetailsManager">
  24. <password-encoderref="passwordEncoder">
  25. <salt-sourceuser-property="username"/>
  26. password-encoder>
  27. authentication-provider>
  28. authentication-manager>
  29. <b:beanid="myAccessDecisionManager"
  30. class="avatar.base.security.MyAccessDecisionManager">
  31. b:bean>
  32. <b:beanid="mySecurityMetadataSource"
  33. class="avatar.base.security.MyInvocationSecurityMetadataSourceService">
  34. b:bean>
  35. b:beans>
  36. applicationContext-service.xml:
  37. xmlversion="1.0"encoding="UTF-8"?>
  38. <beansxmlns="http://www.springframework.org/schema/beans"
  39. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  40. xmlns:util="http://www.springframework.org/schema/util"
  41. xmlns:jee="http://www.springframework.org/schema/jee"
  42. xmlns:aop="http://www.springframework.org/schema/aop"
  43. xmlns:tx="http://www.springframework.org/schema/tx"
  44. xmlns:context="http://www.springframework.org/schema/context"
  45. xsi:schemaLocation="http://www.springframework.org/schema/beans
  46. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  47. http://www.springframework.org/schema/aop
  48. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  49. http://www.springframework.org/schema/tx
  50. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  51. http://www.springframework.org/schema/jee
  52. http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
  53. http://www.springframework.org/schema/context
  54. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  55. http://www.springframework.org/schema/util
  56. http://www.springframework.org/schema/util/spring-util-3.0.xsd">
  57. <beanid="messageSource"
  58. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  59. <propertyname="basename"
  60. value="classpath:org/springframework/security/messages_zh_CN"/>
  61. bean>
  62. <beanid="passwordEncoder"
  63. class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
  64. <beanid="userDetailsManager"class="avatar.base.security.MyUserDetailsService">
  65. <propertyname="pubUsersHome"ref="pubUsersHome"/>
  66. <propertyname="pubAuthoritiesResourcesHome"ref="pubAuthoritiesResourcesHome"/>
  67. <propertyname="dataSource"ref="dataSource"/>
  68. <propertyname="userCache"ref="userCache"/>
  69. bean>
  70. <beanid="userCache"
  71. class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
  72. <propertyname="cache"ref="userEhCache"/>
  73. bean>
  74. <beanid="userEhCache"class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  75. <propertyname="cacheName"value="userCache"/>
  76. <propertyname="cacheManager"ref="cacheManager"/>
  77. bean>
  78. <beanid="cacheManager"
  79. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
  80. <beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
  81. <propertyname="dataSource"ref="dataSource"/>
  82. bean>
  83. beans>

第三种方法扩展后Spring Security3.0.2的验证和授权方法

为了叙述的严谨性,这里说的是Spring Security3.0.2,而非其他版本,这是因为我只读过Spring Security3.0.2的代码,并且在该版本上面扩展自定义的
动态管理用户、角色、权限和资源成功。 估计其他版本的验证和授权方法是差不太多的,因为没有接触过,也不敢大胆猜测。

在扩展后的Spring Security3.0.2中,验证及授权的过程如下:
1、当Web服务器启动时,通过Web.xml中对于Spring Security的配置,加载过滤器链,那么在加载MyFilterSecurityInterceptor类时,会注入 MyInvocationSecurityMetadataSourceService、MyUserDetailsService、 MyAccessDecisionManager类。

2、该MyInvocationSecurityMetadataSourceService类在执行时会提取数据库中所有的用户权限,形成权限列表;
并循环该权限列表,通过每个权限再从数据库中提取出该权限所对应的资源列表,并将资源(URL)作为key,权限列表作为value,形成Map结构的数据。

3、当用户登录时,AuthenticationManager进行响应,通过用户输入的用户名和密码,然后再根据用户定义的密码算法和盐值等进行计算并和数据库比对,
当正确时通过验证。此时MyUserDetailsService进行响应,根据用户名从数据库中提取该用户的权限列表,组合成UserDetails供Spring Security使用。

4、当用户点击某个功能时,触发MyAccessDecisionManager类,该类通过decide方法对用户的资源访问进行拦截。
用户点击某个功能时,实际上是请求某个URL或Action, 无论.jsp也好,.action或.do也好,在请求时无一例外的表现为URL。
还记得第2步时那个Map结构的数据吗? 若用户点击了"login.action"这个URL之后,那么这个URL就跟那个Map结构的数据中的key对比,若两者相同,
则根据该url提取出Map结构的数据中的value来,这说明:若要请求这个URL,必须具有跟这个URL相对应的权限值。这个权限有可能是一个单独的权限,
也有可能是一个权限列表,也就是说,一个URL有可能被多种权限访问。

那好,我们在MyAccessDecisionManager类的decide这个方法里,将通过URL取得的权限列表进行循环,然后跟第 3步中登录的用户所具有的权限进行比对,若相同,则表明该用户具有访问该资源的权利。 不大明白吧? 简单地说, 在数据库中我们定义了访问“LOGIN”这个URL必须是具有ROLE_ADMIN权限的人来访问,那么,登录用户恰恰具有该ROLE_ADMIN权限, 两者的比对过程中,就能够返回TRUE,可以允许该用户进行访问。就这么简单!

不过在第2步的时候,一定要注意,MyInvocationSecurityMetadataSoruceService类的loadResourceDefine()方法中,形成以URL为key,权限列表为value的Map时,
要注意key和Value的对应性,避免Value的不正确对应形成重复,这样会导致没有权限的人也能访问到不该访问到的资源。
还有getAttributes()方法,要有 url.indexOf("?")这样的判断,要通过判断对URL特别是Action问号之前的部分进行匹配,防止用户请求的带参数的URL与你数据库中定义的URL不匹配,造成访问拒绝!

第三种方法BTW

当然,你在设计了7张表之后,那么对于这些之间相互关联的关系内容及信息内容,就得由你来进行维护了,大约有用户、角色、权限、资源的增删 改查,并还需要设置用户和角色、角色和权限、权限和资源之间的关系。可考虑分为三个菜单进行维护,用户设置、角色设置、资源设置。 在用户设置里分别管理用户、用户与角色的关系;在角色设置里管理角色、角色与权限的关系; 在资源设置里分别管理权限、权限与资源的关系等。


第四种方法

第四种方法就是直接修改源码以达到第三种方法的效果。

本来准备是直接从源码修改来的, 但是始终认为修改源码并非终极解决之道,有违OO的精神本质,再者由于时间关系,只是对代码进行了研究,但并没有进行实现或验证。只待以后时间稍稍宽松时 再做为兴趣进行研究,在次不过多的讲解。但据我从代码上来看,一是将从配置文件中获取用户及权限的功能修改为从数据库中提取出来;二是将从配置文件中获取 权限和资源的对应关系修改为从数据库中提取;三是修改User增加相关信息等。

始终还是围绕着JdbcDaoImpl和DefaultFilterInvocationSecurityMetadataSource还有User这3个类进行修改。
以实现从数据库提取用户、角色、权限和资源信息。

有兴趣的就先试试吧,等试好了告诉我一声哈。

Spring Security的优缺点

不可否认,Spring Security依赖于Spring的Ioc、AOP等机制,横切开系统的业务组件,将通用的权限功能注入到业务组件内部,实现了通用功能和业务功能的无 缝整合,但又保证了通用功能和业务功能的实现上的分离,省却了一部分工作量,这是其存在的最重要意义。

但又不可否认,Spring Security所具有的缺乏动态资源管理的硬伤(若是能够提供用户、角色、权限和资源的数据库管理,并且提供管理界面那实在是太完美了,可惜这两样一样都不能实现),又令国人用户爱恨交加。

该何去何从,就请自己做个选择吧!

使用springSecurity3的四种方法概述

那么在Spring Security3的使用中,有4种方法:

一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证;

二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。

三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
目前这种方式已经实现,并经过验证。

四是修改spring security的源代码,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService两个类。
前者是将配置文件或数据库中存储的资源(url)提取出来加工成为url和权限列表的Map供Security使用,后者提取用户名和权限组成一个完整的 (UserDetails)User对象,该对象可以提供用户的详细信息供AuthentationManager进行认证与授权使用。
该方法理论上可行,但是比较暴力,也没有时间实现,未验证,以后再研究。

说明一下,我目前调通的环境为: java1.6 + struts2.1.6 + spring3.0.1 + hibernate3.3.1 + spring security3.0.2 + oracle9i + weblogic10.3,
顺便提一下,目前(2011-4-2)serutity的最新版本为3.1,比较稳定的版本为3.0.5和2.0.6。

当然在进行spring security3的下面4种方法介绍之前,先假定SSH2的环境已经配置完毕,进入正常开发的过程,并且已经导入
spring security3.0.2的5个jar包,分别为:
spring-security-acl-3.0.2.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-taglibs-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
当然还有其他相关的jar包,在此不再赘述。


第一种方法

第一种方法比较简单,可参考Spring Security自带的例子spring-security-samples-tutorial-3.0.2.RELEASE。
这里给出下载网址:http://www.springsource.com/download/community?sid=1087087,不过在下载之前必须填写相应的用户信息,才允许下载。各种版本号的均可以下载。

在spring-security-samples-tutorial-3.0.2.RELEASE的例子里,硬编码的配置请参见applicationContext-security.xml文件中的内容。
里面配置了用户名、经过MD5加密后的密码密文、相关的权限,以及与权相对应的访问资源(URL)。还有对于Session超时时的处理。
特别是因为版本号为3.0.2,因此还增加了对表达式的配置演示,具体内容请参见该例子。

当然你最好运行起该例子来,感受一下,你可以直接将下载下来的解压缩后的文件夹中找到spring-security-samples- tutorial-3.0.2.RELEASE.war文件,然后拷贝到Tomcat的安装目录下的\webapps文件夹下,然后运行Tomcat的服 务器,服务器在启动过程中,会自动解开该war文件,在IE内输入http://localhost:8080/webapps/spring-security-samples-tutorial-3.0.2.RELEASE就可以运行该系统了。在此不再赘述。

第二种方法

第二种方法的代码如下:

使用到的两个表,用户表和权限表的SQL语句。将用户和权限以数据库进行存储。

[sql] view plain copy
  1. createtableUSERS(
  2. USERNAMEVARCHAR2(50)notnull,
  3. PASSWORDVARCHAR2(50)notnull,
  4. ENABLEDNUMBER(1)notnull,
  5. USERNAMECNVARCHAR2(50),
  6. primarykey(username)
  7. )
  8. createtableAUTHORITIES(
  9. USERNAMEVARCHAR2(50)notnull,
  10. AUTHORITYVARCHAR2(50)notnull
  11. )

-- 外键使用户和权限相联。

[sql] view plain copy
  1. Create/Recreateprimary,uniqueandforeignkeyconstraints
  2. altertableAUTHORITIES
  3. addconstraintFK_AUTHORITIES_USERSforeignkey(USERNAME)
  4. referencesUSERS(USERNAME);


可插入几条数据做为试验,首先插入用户:

[sql] view plain copy
  1. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  2. values('lxb','c7d3f4c857bc8c145d6e5d40c1bf23d9',1,'登录用户','AAAHmhAALAAAAAOAAA');
  3. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  4. values('admin','ceb4f32325eda6142bd65215f4c0f371',1,'系统管理员','AAAHmhAALAAAAAPAAA');
  5. insertintousers(USERNAME,PASSWORD,ENABLED,USERNAMECN,ROWID)
  6. values('user','47a733d60998c719cf3526ae7d106d13',1,'普通用户','AAAHmhAALAAAAAPAAB');

再插入角色:

[sql] view plain copy
  1. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  2. values('admin','ROLE_PLATFORMADMIN','AAAHmjAALAAAAAgAAA');
  3. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  4. values('admin','ROLE_SYSADMIN','AAAHmjAALAAAAAgAAB');
  5. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  6. values('lxb','ROLE_LOGIN','AAAHmjAALAAAAAeAAA');
  7. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  8. values('lxb','ROLE_LOGINTOWELCOME','AAAHmjAALAAAAAeAAB');
  9. insertintoauthorities(USERNAME,AUTHORITY,ROWID)
  10. values('user','ROLE_USER','AAAHmjAALAAAAAgAAC');

第二种方法之密码加密

可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过MD5进行加密过的,并且以用户名做为了盐值,最后就成为32位数字这个 样子,这个你可以参见下面applicationContext-Security.xml中的password-encoder和salt- source的配置就会明白。
那么在spring security3中是如何加密的呢?当我们设置了pawwrod-encoder和salt-source之后,Spring Security3会根据配置,采用相匹配的加密算法(比如设置了MD5加密算法)再加上salt-source进行加密,形成32位数字的密文。
比如用户名为yew,密码为yew1234,盐值为用户名yew。那么最后加密的明文为“yew1234{yew}”,密文就为“8fe2657d1599dba8e78a7a0bda8651bb”。

我们在试验过程中,通常喜欢先将几个常用的用户及密码插入数据库进行试验,这种情况下如何得到该用户的密码密文呢?
不妨试试我这个办法,假设,用户名为user,密码明文为user369,而且在配置文件里面设置了以MD5作为加密算法,并以用户名做为盐值。
那么你可以首先将各个信息组合成待加密的密码明文, 应是 密码明文 + { + 盐值 + }, 那么很明显,上述user的密码明文应当是:

user369{user}

拿上述的字串拷贝到http://www.51240.com/md5jiami/网页上的输入框里,点击加密按钮,下面即可生成32位数字的密码密文。

哈哈,屡试不爽啊。这个方法要谨慎使用,一般人我不告诉他。


第二种方法之相关配置

将权限及资源(URL或Action)的关系配置在xml文件中,并且配置与Spring Security3相关的其他配置:

1、applicationContext-Security.xml代码

[html] view plain copy
  1. <b:beansxmlns="http://www.springframework.org/schema/security"
  2. xmlns:b="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beans
  4. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  5. http://www.springframework.org/schema/security
  6. http://www.springframework.org/schema/security/spring-security-3.0.xsd">
  7. <httpauto-config="true"access-denied-page="/accessDenied.jsp">
  8. <intercept-urlpattern="/**/*.jpg"filters="none"/>
  9. <intercept-urlpattern="/**/*.png"filters="none"/>
  10. <intercept-urlpattern="/**/*.gif"filters="none"/>
  11. <intercept-urlpattern="/**/*.css"filters="none"/>
  12. <intercept-urlpattern="/**/*.js"filters="none"/>
  13. <intercept-urlpattern="/login.jsp"filters="none"/>
  14. <intercept-urlpattern="/jsp/forgotpassword.jsp"filters="none"/>
  15. <remember-medata-source-ref="dataSource"/>
  16. <session-managementinvalid-session-url="/sessionTimeout.jsp"/>
  17. http>
  18. <authentication-manageralias="authenticationManager">
  19. <authentication-provideruser-service-ref="userDetailsManager">
  20. <password-encoderref="passwordEncoder">
  21. <salt-sourceuser-property="username"/>
  22. password-encoder>
  23. authentication-provider>
  24. authentication-manager>
  25. b:beans>

2、applicationContext.service.xml:

[html] view plain copy
  1. <beansxmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:util="http://www.springframework.org/schema/util"
  4. xmlns:jee="http://www.springframework.org/schema/jee"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xmlns:context="http://www.springframework.org/schema/context"
  8. xsi:schemaLocation="http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10. http://www.springframework.org/schema/aop
  11. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  12. http://www.springframework.org/schema/tx
  13. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  14. http://www.springframework.org/schema/jee
  15. http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
  16. http://www.springframework.org/schema/context
  17. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  18. http://www.springframework.org/schema/util
  19. http://www.springframework.org/schema/util/spring-util-3.0.xsd">
  20. <beanid="messageSource"
  21. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  22. <propertyname="basename"
  23. value="classpath:org/springframework/security/messages_zh_CN"/>
  24. bean>
  25. <beanid="passwordEncoder"
  26. class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
  27. <beanid="userDetailsManager"
  28. class="org.springframework.security.provisioning.JdbcUserDetailsManager">
  29. <propertyname="dataSource"ref="dataSource"/>
  30. <propertyname="userCache"ref="userCache"/>
  31. bean>
  32. <beanid="userCache"
  33. class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
  34. <propertyname="cache"ref="userEhCache"/>
  35. bean>
  36. <beanid="userEhCache"class="org.springframework.cache.ehcache.EhCacheFactoryBean">
  37. <propertyname="cacheName"value="userCache"/>
  38. <propertyname="cacheManager"ref="cacheManager"/>
  39. bean>
  40. <beanid="cacheManager"
  41. class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
  42. <beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
  43. <propertyname="dataSource"ref="dataSource"/>
  44. bean>
  45. beans>



3、web.xml:

[html] view plain copy
  1. <web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  4. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  5. <context-param>
  6. <param-name>webAppRootKeyparam-name>
  7. <param-value>log.rootparam-value>
  8. context-param>
  9. <context-param>
  10. <param-name>log4jConfigLocationparam-name>
  11. <param-value>classpath:/log4j.propertiesparam-value>
  12. context-param>
  13. <context-param>
  14. <param-name>log4jRefreshIntervalparam-name>
  15. <param-value>60000param-value>
  16. context-param>
  17. <listener>
  18. <listener-class>org.springframework.web.util.Log4jConfigListenerlistener-class>
  19. listener>
  20. <listener>
  21. <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  22. listener>
  23. <filter>
  24. <filter-name>characterEncodingFilterfilter-name>
  25. <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
  26. <init-param>
  27. <param-name>encodingparam-name>
  28. <param-value>gbkparam-value>
  29. init-param>
  30. <init-param>
  31. <param-name>ForceEncodingparam-name>
  32. <param-value>trueparam-value>
  33. init-param>
  34. filter>
  35. <filter-mapping>
  36. <filter-name>characterEncodingFilterfilter-name>
  37. <url-pattern>/*url-pattern>
  38. filter-mapping>
  39. <filter>
  40. <filter-name>springSecurityFilterChainfilter-name>
  41. <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
  42. filter>
  43. <filter-mapping>
  44. <filter-name>springSecurityFilterChainfilter-name>
  45. <url-pattern>/*url-pattern>
  46. filter-mapping>
  47. <filter>
  48. <filter-name>struts2filter-name>
  49. <filter-class>
  50. org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  51. filter-class>
  52. filter>
  53. <filter-mapping>
  54. <filter-name>struts2filter-name>
  55. <url-pattern>/*url-pattern>
  56. filter-mapping>
  57. <filter>
  58. <filter-name>struts-cleanupfilter-name>
  59. <filter-class>
  60. org.apache.struts2.dispatcher.ActionContextCleanUp
  61. filter-class>
  62. filter>
  63. <filter-mapping>
  64. <filter-name>struts-cleanupfilter-name>
  65. <url-pattern>/*url-pattern>
  66. filter-mapping>
  67. <listener>
  68. <listener-class>
  69. org.springframework.web.util.IntrospectorCleanupListener
  70. listener-class>
  71. listener>
  72. <session-config>
  73. <session-timeout>20session-timeout>
  74. session-config>
  75. <welcome-file-list>
  76. <welcome-file>login.jspwelcome-file>
  77. welcome-file-list>
  78. web-app>
令人欣喜的是,整个Security配置过程中,除了建立数据库和编写配置文件之外,不需要编写任何的代码。怎么样? 有点意思吧!

第二种方法中遇见的问题

当然,首次使用Spring serutiry,在整合的过程中,我还是遇见了不少问题,当然有些问题比如找不到类呀,包呀,和框架的整合呀等问题不作为谈论的重点。主要还是探讨Spring Security的配置和注意事项的问题。

我在其中碰到的对我印象最深的问题是,当完全配置好之后,重启Web服务器,却发现Spring Security不能拦截任何的URL了,这使我感到惊诧,因为在去年时,我已经将该框架搭建完成,在当时正是使用的该种方法,并且在试验是否能够拦截 jsp文件时进行了确认是没有问题的。

接下来我又整理了一下applicationContext-security.xml的文件才发现, 除了不需要进行检测的图片及登录页面之外,没有对任何的资源和权限之间的对应关系进行配置,参见下面的代码:

[html] view plain copy
  1. <httpauto-config="true"access-denied-page="/accessDenied.jsp">
  2. <intercept-urlpattern="/**/*.jpg"filters="none"/>
  3. <intercept-urlpattern="/**/*.png"filters="none"/>
  4. <intercept-urlpattern="/**/*.gif"filters="none"/>
  5. <intercept-urlpattern="/**/*.css"filters="none"/>
  6. <intercept-urlpattern="/**/*.js"filters="none"/>
  7. <intercept-urlpattern="/login.jsp"filters="none"/>
  8. <intercept-urlpattern="/jsp/forgotpassword.jsp"filters="none"/>

你可能感兴趣的:(Spring security控制权限的几种方法)