码迷,mamicode.com
首页 > 编程语言 > 详细

Spring Security3的四种方法概述

时间:2015-05-26 22:48:34      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

 

使用Spring Security3的四种方法概述

 

 

  那么在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语句。将用户和权限以数据库进行存储。

 

技术分享
 1  create table USERS(
 2   USERNAME   VARCHAR2(50) not null,
 3   PASSWORD   VARCHAR2(50) not null,
 4   ENABLED    NUMBER(1) not null,
 5   USERNAMECN VARCHAR2(50),
 6   primary key( username )
 7 )
 8 
 9 create table AUTHORITIES(
10   USERNAME  VARCHAR2(50) not null,
11   AUTHORITY VARCHAR2(50) not null
12 )
13 
14 -- 外键使用户和权限相联。
15 
16 Create/Recreate primary, unique and foreign key constraints 
17 alter table AUTHORITIES
18 add constraint FK_AUTHORITIES_USERS foreign key (USERNAME)
19 references USERS (USERNAME);
20 
21 
22 可插入几条数据做为试验,首先插入用户:
23 
24 insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
25 values (lxb, c7d3f4c857bc8c145d6e5d40c1bf23d9, 1, 登录用户, AAAHmhAALAAAAAOAAA);
26 
27 insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
28 values (admin, ceb4f32325eda6142bd65215f4c0f371, 1, 系统管理员, AAAHmhAALAAAAAPAAA);
29 
30 insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
31 values (user, 47a733d60998c719cf3526ae7d106d13, 1, 普通用户, AAAHmhAALAAAAAPAAB);
32 
33 再插入角色:
34 
35 insert into authorities (USERNAME, AUTHORITY, ROWID)
36 values (admin, ROLE_PLATFORMADMIN, AAAHmjAALAAAAAgAAA);
37 
38 insert into authorities (USERNAME, AUTHORITY, ROWID)
39 values (admin, ROLE_SYSADMIN, AAAHmjAALAAAAAgAAB);
40 
41 insert into authorities (USERNAME, AUTHORITY, ROWID)
42 values (lxb, ROLE_LOGIN, AAAHmjAALAAAAAeAAA);
43 
44 insert into authorities (USERNAME, AUTHORITY, ROWID)
45 values (lxb, ROLE_LOGINTOWELCOME, AAAHmjAALAAAAAeAAB);
46 
47 insert into authorities (USERNAME, AUTHORITY, ROWID)
48 values (user, ROLE_USER, AAAHmjAALAAAAAgAAC);
View Code

 


第二种方法之密码加密

    可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过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代码:

 

技术分享
 1 <b:beans xmlns="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 
 8  <http auto-config="true" access-denied-page="/accessDenied.jsp">
 9   <!-- 不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。 -->
10   <intercept-url pattern="/**/*.jpg" filters="none" />
11   <intercept-url pattern="/**/*.png" filters="none" />
12   <intercept-url pattern="/**/*.gif" filters="none" />
13   <intercept-url pattern="/**/*.css" filters="none" />
14   <intercept-url pattern="/**/*.js" filters="none" />
15   <!-- 登录页面和忘记密码页面不过滤 -->
16   <intercept-url pattern="/login.jsp" filters="none" />
17   <intercept-url pattern="/jsp/forgotpassword.jsp"   filters="none" /> 
18 
19    <!-- 下面是对Action配置。表示具有访问/unitsManager资源的用户必须具有ROLE_PLATFORMADMIN的权限。
20                       当用户登录时,SS3将用户的所有权限从数据库中提取出来,形成列表。 当用户访问该资源时,SS3将
21                       登录用户的权限列表提出来跟下面配置的权限进行比对,若有,则允许访问,若没有,则给出AccessDeniedException。-->
22   <intercept-url pattern="/unitsManager"   access="ROLE_PLATFORMADMIN" />
23   <intercept-url pattern="/usersManager"  access="ROLE_PLATFORMADMIN" />
24 
25   <intercept-url pattern="/horizontalQuery"  access="ROLE_PLATFORMADMIN" />
26    
27   <intercept-url pattern="/verticalQuery"    access="ROLE_PLATFORMADMIN" />
28   
29   <form-login login-page="/login.jsp"  authentication-failure-url="/login.jsp?error=true"   default-target-url="/index.jsp" />
30 
31   <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) -->
32   <remember-me data-source-ref="dataSource" />
33   
34   <!-- 检测失效的sessionId,超时时定位到另外一个URL -->
35   <session-management invalid-session-url="/sessionTimeout.jsp" />
36   
37  </http>
38 
39  <!-- 注意能够为authentication-manager 设置alias别名  -->
40  <authentication-manager alias="authenticationManager">
41       <authentication-provider user-service-ref="userDetailsManager">
42            <password-encoder ref="passwordEncoder">
43                 <!-- 用户名做为盐值 -->
44                 <salt-source user-property="username" />
45            </password-encoder>
46       </authentication-provider>
47  </authentication-manager>
48 
49 </b:beans>
View Code

 

    2、applicationContext.service.xml:

 

技术分享
 1 <beans xmlns="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  
21  <!-- 定义上下文返回的消息的国际化。 -->
22  <bean id="messageSource"
23   class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
24   <property name="basename"
25    value="classpath:org/springframework/security/messages_zh_CN"/>
26  </bean>
27 
28  <!--   事件监听:实现了 ApplicationListener监听接口,包括AuthenticationCredentialsNotFoundEvent 事件,
29   AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事件 -->
30  <bean  class="org.springframework.security.authentication.event.LoggerListener" />
31 
32  <!-- 用户的密码加密或解密 -->
33  <bean id="passwordEncoder"
34   class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
35 
36 
37  <!-- 用户详细信息管理 : 数据源、用户缓存、启用用户组功能。  -->
38  <bean id="userDetailsManager"
39   class="org.springframework.security.provisioning.JdbcUserDetailsManager">
40   <property name="dataSource" ref="dataSource" />
41   <property name="userCache" ref="userCache" />
42  </bean> 
43  
44  <bean id="userCache"
45   class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
46   <property name="cache" ref="userEhCache" />
47  </bean> 
48  
49  
50  <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
51   <property name="cacheName" value="userCache" />
52   <property name="cacheManager" ref="cacheManager" />
53  </bean>
54  
55  <!-- 缓存用户管理 -->
56  <bean id="cacheManager"
57   class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
58   
59 
60  <!-- spring security自带的与权限有关的数据读写Jdbc模板 -->
61  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
62   <property name="dataSource" ref="dataSource" />
63  </bean>
64 
65 </beans>
View Code

 

    3、web.xml:

 

技术分享
  1  <web-app version="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 
  6 
  7  <!-- 设置log4j存放Log文件位置(通过spring统一进行管理) -->
  8  <context-param>
  9   <param-name>webAppRootKey</param-name>
 10   <param-value>log.root</param-value>
 11  </context-param>
 12 
 13  <!-- 加载log4j的配置文件 -->
 14  <context-param>
 15   <param-name>log4jConfigLocation</param-name>
 16   <param-value>classpath:/log4j.properties</param-value>
 17  </context-param>
 18 
 19  <!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond-->
 20  <context-param>
 21   <param-name>log4jRefreshInterval</param-name>
 22   <param-value>60000</param-value>
 23  </context-param>
 24 
 25  <!--Spring用于log4j初始化的监听器-->
 26  <listener>
 27   <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 28  </listener>
 29 
 30  <!--
 31   加载Spring XML配置文件,Spring安全配置及各类资源文件,暂不加
 32   /WEB-INF/applicationContext-security.xml,
 33  -->
 34  <context-param>
 35   <param-name>contextConfigLocation</param-name>
 36   <param-value>
 37            /WEB-INF/applicationContext*.xml,
 38            classpath*:applicationContext.xml
 39         </param-value>
 40  </context-param>
 41 
 42  <!--spring监听器的配置,用于在启动Web容器时,自动装配ApplicationContext的配置信息-->
 43  <listener>
 44   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 45  </listener>
 46 
 47  <!-- 使用Spring中的过滤器解决在请求和应答中的中文乱码问题 -->
 48  <filter>
 49   <filter-name>characterEncodingFilter</filter-name>
 50   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
 51   <init-param>
 52    <param-name>encoding</param-name>
 53    <param-value>gbk</param-value>
 54   </init-param>
 55   <init-param>
 56    <!--强制转换编码(request和response均适用) -->
 57    <param-name>ForceEncoding</param-name>
 58    <param-value>true</param-value>
 59   </init-param>
 60  </filter>
 61 
 62  <filter-mapping>
 63   <filter-name>characterEncodingFilter</filter-name>
 64   <url-pattern>/*</url-pattern>
 65  </filter-mapping>
 66 
 67  
 68  <!-- Spring Secutiry3.0.2的过滤器链配置  -->
 69  <filter>
 70   <filter-name>springSecurityFilterChain</filter-name>
 71   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 72  </filter>
 73 
 74  <filter-mapping>
 75   <filter-name>springSecurityFilterChain</filter-name>
 76   <url-pattern>/*</url-pattern>
 77  </filter-mapping>
 78 
 79  
 80     <!-- 配置Struts2的FilterDispathcer的Filter -->
 81     <filter>
 82         <filter-name>struts2</filter-name>
 83         <filter-class>
 84          org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 85         </filter-class>        
 86     </filter>
 87 
 88  <!-- struts2用以处理用户Web请求的路径模式-->
 89     <filter-mapping>
 90         <filter-name>struts2</filter-name>
 91         <url-pattern>/*</url-pattern>
 92     </filter-mapping>
 93     
 94    
 95  
 96  <!-- 避免乱码问题 -->
 97  <filter>
 98         <filter-name>struts-cleanup</filter-name>
 99         <filter-class>
100             org.apache.struts2.dispatcher.ActionContextCleanUp
101         </filter-class>
102     </filter>
103     
104     <filter-mapping>
105         <filter-name>struts-cleanup</filter-name>
106         <url-pattern>/*</url-pattern>
107     </filter-mapping>
108     
109     <!-- Spring刷新Interceptor防止内存泄漏  -->
110     <listener>
111      <listener-class>
112      org.springframework.web.util.IntrospectorCleanupListener
113      </listener-class>
114     </listener>
115  
116 
117  <!-- 设置session 超时时间为20分钟  -->
118  <session-config>
119   <session-timeout>20</session-timeout>
120  </session-config>
121 
122  <!--系统欢迎页面-->
123  <welcome-file-list>
124   <welcome-file>login.jsp</welcome-file>
125  </welcome-file-list>
126 
127 </web-app>
View Code

 


    令人欣喜的是,整个Security配置过程中,除了建立数据库和编写配置文件之外,不需要编写任何的代码。怎么样? 有点意思吧!

第二种方法中遇见的问题

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

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

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

技术分享
 1 <http auto-config="true" access-denied-page="/accessDenied.jsp">
 2   <!-- 不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。 -->
 3   <intercept-url pattern="/**/*.jpg" filters="none" />
 4   <intercept-url pattern="/**/*.png" filters="none" />
 5   <intercept-url pattern="/**/*.gif" filters="none" />
 6   <intercept-url pattern="/**/*.css" filters="none" />
 7   <intercept-url pattern="/**/*.js" filters="none" />
 8   <!-- 登录页面和忘记密码页面不过滤 -->
 9   <intercept-url pattern="/login.jsp" filters="none" />
10   <intercept-url pattern="/jsp/forgotpassword.jsp" filters="none" /> 
11 
12              <!-- 下面是对Struts2的Action请求时的配置。注意在前面加/,否则不会被SS3进行拦截验证。
13                   表示具有访问/unitsManager资源的用户必须具有ROLE_PLATFORMADMIN的权限。
14                   当用户登录时,SS3将用户的所有权限从数据库中提取出来,形成列表。 当用户访问该资源时,
15                   SS3将登录用户的权限列表提出来跟下面配置的权限进行比对,若有,则允许访问,若没有,
16                   则给出AccessDeniedException。 
17   <intercept-url pattern="/unitsManager"  access="ROLE_PLATFORMADMIN" />
18   <intercept-url pattern="/usersManager"  access="ROLE_PLATFORMADMIN" />
19   <intercept-url pattern="/horizontalQuery" access="ROLE_PLATFORMADMIN" /> 
20   <intercept-url pattern="/verticalQuery"  access="ROLE_PLATFORMADMIN" />   -->
21   
22   <form-login login-page="/login.jsp" 
23    authentication-failure-url="/login.jsp?error=true"
24    default-target-url="/index.jsp" />
25 
26   <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) -->
27   <remember-me data-source-ref="dataSource" />
28   
29   <!-- 检测失效的sessionId,超时时定位到另外一个URL -->
30   <session-management invalid-session-url="/sessionTimeout.jsp" />
31   
32  </http>
View Code

 

    这样一来,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文件中的<http>元素下面。
    什么,你看不到? 忘记告诉你了,从spring security2开始,就使用了命名空间,若你在<http>中设置了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个关键类):

 

技术分享
 1 /*
 2  * @(#) MyFilterSecurityInterceptor.java  2011-3-23 上午07:53:03
 3  *
 4  * Copyright 2011 by Sparta 
 5  */
 6 
 7 package avatar.base.security;
 8 
 9 import java.io.IOException;
10 
11 import javax.servlet.Filter;
12 import javax.servlet.FilterChain;
13 import javax.servlet.FilterConfig;
14 import javax.servlet.ServletException;
15 import javax.servlet.ServletRequest;
16 import javax.servlet.ServletResponse;
17 
18 import org.springframework.security.access.SecurityMetadataSource;
19 import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
20 import org.springframework.security.access.intercept.InterceptorStatusToken;
21 import org.springframework.security.web.FilterInvocation;
22 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
23 
24 /**
25  * 该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。
26  * securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。
27  * 该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中,
28  * 供Spring Security使用,用于权限校验。
29  * @author sparta 11/3/29
30  *
31  */
32 
33 public class MyFilterSecurityInterceptor 
34  extends AbstractSecurityInterceptor
35  implements Filter{
36  
37 
38  private FilterInvocationSecurityMetadataSource securityMetadataSource;
39  
40  public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)
41  throws IOException, ServletException{
42   
43   FilterInvocation fi = new FilterInvocation( request, response, chain );
44   invoke(fi);
45   
46  }
47  
48  public FilterInvocationSecurityMetadataSource getSecurityMetadataSource(){
49   return this.securityMetadataSource;
50  }
51  
52  public Class<? extends Object> getSecureObjectClass(){
53   return FilterInvocation.class;
54  }
55 
56  
57  public void invoke( FilterInvocation fi ) throws IOException, ServletException{
58   
59   InterceptorStatusToken  token = super.beforeInvocation(fi);
60   
61   try{
62    fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
63   }finally{
64    super.afterInvocation(token, null);
65   }
66   
67  }
68   
69  
70  @Override
71  public SecurityMetadataSource obtainSecurityMetadataSource(){
72   return this.securityMetadataSource;
73  }
74  
75  
76  public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource){
77   this.securityMetadataSource = securityMetadataSource;
78  }
79  
80  
81  public void destroy(){
82   
83  }
84  
85  public void init( FilterConfig filterconfig ) throws ServletException{
86   
87  }
88  
89  
90 }
View Code

 

技术分享
  1 /*
  2  * @(#) MyInvocationSecurityMetadataSourceService.java 
  3  *
  4  */
  5 
  6 package avatar.base.security;
  7 
  8 import java.util.ArrayList;
  9 import java.util.Collection;
 10 import java.util.HashMap;
 11 import java.util.Iterator;
 12 import java.util.List;
 13 import java.util.Map;
 14 
 15 import org.hibernate.Session;
 16 import org.hibernate.SessionFactory;
 17 import org.springframework.beans.factory.annotation.Autowired;
 18 import org.springframework.context.ApplicationContext;
 19 import org.springframework.context.support.ClassPathXmlApplicationContext;
 20 import org.springframework.security.access.ConfigAttribute;
 21 import org.springframework.security.access.SecurityConfig;
 22 import org.springframework.security.core.GrantedAuthority;
 23 import org.springframework.security.core.context.SecurityContextHolder;
 24 import org.springframework.security.core.userdetails.UserDetails;
 25 import org.springframework.security.web.FilterInvocation;
 26 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
 27 import org.springframework.security.web.util.AntUrlPathMatcher;
 28 import org.springframework.security.web.util.UrlMatcher;
 29 import org.springframework.stereotype.Service;
 30 
 31 import avatar.base.security.dao.PubAuthoritiesResourcesHome;
 32 
 33 /**
 34  * 最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。 此类在初始化时,应该取到所有资源及其对应角色的定义。
 35  * 
 36  */
 37 @Service
 38 public class MyInvocationSecurityMetadataSourceService implements
 39   FilterInvocationSecurityMetadataSource {
 40 
 41  @Autowired
 42  private PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome;
 43 
 44  private UrlMatcher urlMatcher = new AntUrlPathMatcher();
 45 
 46  private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
 47 
 48  public MyInvocationSecurityMetadataSourceService() {
 49   loadResourceDefine();
 50  }
 51 
 52  private void loadResourceDefine() {
 53   ApplicationContext context = new ClassPathXmlApplicationContext(
 54     "classpath:applicationContext.xml");
 55 
 56   SessionFactory sessionFactory = (SessionFactory) context
 57     .getBean("sessionFactory");
 58 
 59   Session session = sessionFactory.openSession();
 60 
 61   String username = "";
 62   String sql = "";
 63 
 64   // 在Web服务器启动时,提取系统中的所有权限。
 65   sql = "select authority_name from pub_authorities";
 66 
 67   List<String> query = session.createSQLQuery(sql).list();
 68 
 69   /*
 70    * 应当是资源为key, 权限为value。 资源通常为url, 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。
 71    * sparta
 72    */
 73   resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
 74 
 75   for (String auth : query) {
 76    ConfigAttribute ca = new SecurityConfig(auth);
 77 
 78    List<String> query1 = session
 79      .createSQLQuery(
 80        "select b.resource_string "
 81          + "from Pub_Authorities_Resources a, Pub_Resources b, "
 82          + "Pub_authorities c where a.resource_id = b.resource_id "
 83          + "and a.authority_id=c.authority_id and c.Authority_name=‘"
 84          + auth + "‘").list();
 85 
 86    for (String res : query1) {
 87     String url = res;
 88     
 89     /*
 90      * 判断资源文件和权限的对应关系,如果已经存在相关的资源url,则要通过该url为key提取出权限集合,将权限增加到权限集合中。
 91      * sparta
 92      */
 93     if (resourceMap.containsKey(url)) {
 94 
 95      Collection<ConfigAttribute> value = resourceMap.get(url);
 96      value.add(ca);
 97      resourceMap.put(url, value);
 98     } else {
 99      Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
100      atts.add(ca);
101      resourceMap.put(url, atts);
102     }
103 
104    }
105 
106   }
107 
108  }
109 
110  @Override
111  public Collection<ConfigAttribute> getAllConfigAttributes() {
112 
113   return null;
114  }
115 
116  // 根据URL,找到相关的权限配置。
117  @Override
118  public Collection<ConfigAttribute> getAttributes(Object object)
119    throws IllegalArgumentException {
120 
121   // object 是一个URL,被用户请求的url。
122   String url = ((FilterInvocation) object).getRequestUrl();
123   
124         int firstQuestionMarkIndex = url.indexOf("?");
125 
126         if (firstQuestionMarkIndex != -1) {
127             url = url.substring(0, firstQuestionMarkIndex);
128         }
129 
130   Iterator<String> ite = resourceMap.keySet().iterator();
131 
132   while (ite.hasNext()) {
133    String resURL = ite.next();
134    
135    if (urlMatcher.pathMatchesUrl(url, resURL)) {
136 
137     return resourceMap.get(resURL);
138    }
139   }
140 
141   return null;
142  }
143 
144  @Override
145  public boolean supports(Class<?> arg0) {
146 
147   return true;
148  }
149 
150 }
View Code

 

技术分享
  1 /*
  2  * @(#) MyUserDetailsService.java 
  3  *
  4  *
  5  */
  6 
  7 package avatar.base.security;
  8 
  9 
 10 import java.util.ArrayList;
 11 import java.util.Collection;
 12 
 13 
 14 import javax.sql.DataSource;
 15 
 16 
 17 import org.springframework.beans.factory.annotation.Autowired;
 18 import org.springframework.dao.DataAccessException;
 19 import org.springframework.security.core.GrantedAuthority;
 20 import org.springframework.security.core.userdetails.User;
 21 import org.springframework.security.core.userdetails.UserCache;
 22 import org.springframework.security.core.userdetails.UserDetails;
 23 import org.springframework.security.core.userdetails.UserDetailsService;
 24 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 25 import org.springframework.stereotype.Service;
 26 
 27 import avatar.base.security.dao.PubAuthoritiesResourcesHome;
 28 import avatar.base.security.dao.PubUsersHome;
 29 
 30 
 31 /**
 32  *该类的主要作用是为Spring Security提供一个经过用户认证后的UserDetails。
 33  *该UserDetails包括用户名、密码、是否可用、是否过期等信息。
 34  *sparta 11/3/29
 35  */
 36 @Service
 37 public class MyUserDetailsService implements UserDetailsService {
 38 
 39  @Autowired
 40  private PubUsersHome pubUsersHome;
 41  
 42  @Autowired
 43  private PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome;
 44  
 45  @Autowired
 46  private DataSource dataSource;
 47  
 48  @Autowired
 49  private UserCache userCache;
 50 
 51  @Override
 52  public UserDetails loadUserByUsername(String username)
 53    throws UsernameNotFoundException, DataAccessException {
 54   
 55   Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
 56   
 57   
 58   //得到用户的权限
 59   auths = pubUsersHome.loadUserAuthoritiesByName( username );
 60   
 61   String password = null;
 62   
 63   //取得用户的密码
 64   password = pubUsersHome.getPasswordByUsername( username );  
 65    
 66   return new User( username, password, true, "", true, true, true, auths);
 67  }
 68   
 69  //set PubUsersHome
 70  public void setPubUsersHome( PubUsersHome pubUsersHome ){
 71   this.pubUsersHome = pubUsersHome;
 72   
 73  }
 74  
 75  public PubUsersHome getPubUsersHome(){
 76   return pubUsersHome;
 77  }
 78  
 79  
 80  //set PubAuthoritiesResourcesHome
 81  public void setPubAuthoritiesResourcesHome( PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome ){
 82   this.pubAuthoritiesResourcesHome = pubAuthoritiesResourcesHome;
 83   
 84  }
 85  
 86  public PubAuthoritiesResourcesHome getPubAuthoritiesResourcesHome(){
 87   return pubAuthoritiesResourcesHome;
 88   
 89  }
 90  
 91  //set DataSource
 92  public void setDataSource( DataSource dataSource ){
 93   this.dataSource = dataSource;
 94  }
 95  
 96  public DataSource getDataSource(){
 97   return dataSource;
 98  }
 99  
100  //设置用户缓存功能。
101     public void setUserCache(UserCache userCache) {
102         this.userCache = userCache;
103     }
104     
105     public UserCache getUserCache(){
106      return this.userCache;
107     }
108  
109 }
View Code

 

技术分享
 1 /*
 2  * @(#) MyAccessDecisionManager.java 
 3  *
 4  */
 5 
 6 package avatar.base.security;
 7 
 8 import java.util.Collection;
 9 import java.util.Iterator;
10 
11 import org.springframework.security.access.AccessDecisionManager;
12 import org.springframework.security.access.AccessDeniedException;
13 import org.springframework.security.access.ConfigAttribute;
14 import org.springframework.security.access.SecurityConfig;
15 import org.springframework.security.authentication.InsufficientAuthenticationException;
16 import org.springframework.security.core.Authentication;
17 import org.springframework.security.core.GrantedAuthority;
18 
19 /**
20  *AccessdecisionManager在Spring security中是很重要的。
21  *
22  *在验证部分简略提过了,所有的Authentication实现需要保存在一个GrantedAuthority对象数组中。 
23  *这就是赋予给主体的权限。 GrantedAuthority对象通过AuthenticationManager
24  *保存到 Authentication对象里,然后从AccessDecisionManager读出来,进行授权判断。 
25  *
26  *Spring Security提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。 
27  *一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。 
28  *这个 AccessDecisionManager 被AbstractSecurityInterceptor调用,
29  *它用来作最终访问控制的决定。 这个AccessDecisionManager接口包含三个方法: 
30  *
31  void decide(Authentication authentication, Object secureObject,
32     List<ConfigAttributeDefinition> config) throws AccessDeniedException;
33  boolean supports(ConfigAttribute attribute);
34  boolean supports(Class clazz);
35  
36   从第一个方法可以看出来,AccessDecisionManager使用方法参数传递所有信息,这好像在认证评估时进行决定。 
37   特别是,在真实的安全方法期望调用的时候,传递安全Object启用那些参数。 
38   比如,让我们假设安全对象是一个MethodInvocation。 
39   很容易为任何Customer参数查询MethodInvocation,
40   然后在AccessDecisionManager里实现一些有序的安全逻辑,来确认主体是否允许在那个客户上操作。 
41   如果访问被拒绝,实现将抛出一个AccessDeniedException异常。
42 
43   这个 supports(ConfigAttribute) 方法在启动的时候被
44   AbstractSecurityInterceptor调用,来决定AccessDecisionManager
45   是否可以执行传递ConfigAttribute。 
46   supports(Class)方法被安全拦截器实现调用,
47   包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。
48  */
49 public class MyAccessDecisionManager implements AccessDecisionManager {
50  
51  public void decide( Authentication authentication, Object object, 
52    Collection<ConfigAttribute> configAttributes) 
53   throws AccessDeniedException, InsufficientAuthenticationException{
54   
55   if( configAttributes == null ) {
56    return ;
57   }
58   
59   Iterator<ConfigAttribute> ite = configAttributes.iterator();
60   
61   while( ite.hasNext()){
62    
63    ConfigAttribute ca = ite.next();
64    String needRole = ((SecurityConfig)ca).getAttribute();
65    
66    //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。
67    for( GrantedAuthority ga: authentication.getAuthorities()){
68     
69     if(needRole.trim().equals(ga.getAuthority().trim())){
70 
71      return;
72     }
73     
74    }
75    
76   }
77   
78   throw new AccessDeniedException("");
79   
80  }
81  
82  public boolean supports( ConfigAttribute attribute ){
83   
84   return true;
85 
86  }
87  
88  public boolean supports(Class<?> clazz){
89   return true;
90 
91  }
92  
93 
94 }
View Code

 


数据库的SQL及预置数据:

技术分享
  1 prompt PL/SQL Developer import file
  2 prompt Created on 2011年6月1日 by Administrator
  3 set feedback off
  4 set define off
  5 prompt Creating SYS_AUTHORITIES
  6 create table SYS_AUTHORITIES
  7 (
  8   AUTHORITY_ID   VARCHAR2(32) not null,
  9   AUTHORITY_NAME VARCHAR2(40),
 10   AUTHORITY_DESC VARCHAR2(100),
 11   ENABLED        NUMBER(1),
 12   ISSYS          NUMBER(1),
 13   MODULE         VARCHAR2(4)
 14 )
 15 tablespace SCJD
 16   pctfree 10
 17   initrans 1
 18   maxtrans 255
 19   storage
 20   (
 21     initial 64K
 22     minextents 1
 23     maxextents unlimited
 24   );
 25 comment on table SYS_AUTHORITIES
 26   is 权限表;
 27 comment on column SYS_AUTHORITIES.MODULE
 28   is 所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。;
 29 alter table SYS_AUTHORITIES
 30   add constraint PK_PUB_AUTHORITIES primary key (AUTHORITY_ID)
 31   using index 
 32   tablespace SCJD
 33   pctfree 10
 34   initrans 2
 35   maxtrans 255
 36   storage
 37   (
 38     initial 64K
 39     minextents 1
 40     maxextents unlimited
 41   );
 42 
 43 prompt Creating SYS_RESOURCES
 44 create table SYS_RESOURCES
 45 (
 46   RESOURCE_ID     VARCHAR2(32) not null,
 47   RESOURCE_NAME   VARCHAR2(100),
 48   RESOURCE_DESC   VARCHAR2(100),
 49   RESOURCE_TYPE   VARCHAR2(40),
 50   RESOURCE_STRING VARCHAR2(200),
 51   PRIORITY        NUMBER(1),
 52   ENABLED         NUMBER(1),
 53   ISSYS           NUMBER(1),
 54   MODULE          VARCHAR2(4)
 55 )
 56 tablespace SCJD
 57   pctfree 10
 58   initrans 1
 59   maxtrans 255
 60   storage
 61   (
 62     initial 64K
 63     minextents 1
 64     maxextents unlimited
 65   );
 66 comment on table SYS_RESOURCES
 67   is 资源表;
 68 comment on column SYS_RESOURCES.PRIORITY
 69   is (暂不用,保留);
 70 comment on column SYS_RESOURCES.MODULE
 71   is 所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。 (暂不用,保留);
 72 alter table SYS_RESOURCES
 73   add constraint PK_PUB_RESOURCES primary key (RESOURCE_ID)
 74   using index 
 75   tablespace SCJD
 76   pctfree 10
 77   initrans 2
 78   maxtrans 255
 79   storage
 80   (
 81     initial 64K
 82     minextents 1
 83     maxextents unlimited
 84   );
 85 
 86 prompt Creating SYS_AUTHORITIES_RESOURCES
 87 create table SYS_AUTHORITIES_RESOURCES
 88 (
 89   ID           NUMBER(13) not null,
 90   AUTHORITY_ID VARCHAR2(32),
 91   RESOURCE_ID  VARCHAR2(32),
 92   ENABLED      NUMBER(1)
 93 )
 94 tablespace SCJD
 95   pctfree 10
 96   initrans 1
 97   maxtrans 255
 98   storage
 99   (
100     initial 64K
101     minextents 1
102     maxextents unlimited
103   );
104 comment on table SYS_AUTHORITIES_RESOURCES
105   is 权限资源表;
106 alter table SYS_AUTHORITIES_RESOURCES
107   add constraint PK_PUB_AUTHORITIES_RE primary key (ID)
108   using index 
109   tablespace SCJD
110   pctfree 10
111   initrans 2
112   maxtrans 255
113   storage
114   (
115     initial 64K
116     minextents 1
117     maxextents unlimited
118   );
119 alter table SYS_AUTHORITIES_RESOURCES
120   add constraint FK_PUB_AUTHORITIES_RE_AU foreign key (AUTHORITY_ID)
121   references SYS_AUTHORITIES (AUTHORITY_ID);
122 alter table SYS_AUTHORITIES_RESOURCES
123   add constraint FK_PUB_AUTHORITIES_RE_RE foreign key (RESOURCE_ID)
124   references SYS_RESOURCES (RESOURCE_ID);
125 
126 prompt Creating SYS_ROLES
127 create table SYS_ROLES
128 (
129   ROLE_ID   VARCHAR2(32) not null,
130   ROLE_NAME VARCHAR2(40),
131   ROLE_DESC VARCHAR2(100),
132   ENABLED   NUMBER(1),
133   ISSYS     NUMBER(1),
134   MODULE    VARCHAR2(4)
135 )
136 tablespace SCJD
137   pctfree 10
138   initrans 1
139   maxtrans 255
140   storage
141   (
142     initial 64K
143     minextents 1
144     maxextents unlimited
145   );
146 comment on table SYS_ROLES
147   is 角色表;
148 comment on column SYS_ROLES.MODULE
149   is 所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。;
150 alter table SYS_ROLES
151   add constraint PK_PUB_ROLES primary key (ROLE_ID)
152   using index 
153   tablespace SCJD
154   pctfree 10
155   initrans 2
156   maxtrans 255
157   storage
158   (
159     initial 64K
160     minextents 1
161     maxextents unlimited
162   );
163 
164 prompt Creating SYS_ROLES_AUTHORITIES
165 create table SYS_ROLES_AUTHORITIES
166 (
167   ID           NUMBER(13) not null,
168   ROLE_ID      VARCHAR2(32),
169   AUTHORITY_ID VARCHAR2(32),
170   ENABLED      NUMBER(1)
171 )
172 tablespace SCJD
173   pctfree 10
174   initrans 1
175   maxtrans 255
176   storage
177   (
178     initial 64K
179     minextents 1
180     maxextents unlimited
181   );
182 comment on table SYS_ROLES_AUTHORITIES
183   is 角色权限表;
184 alter table SYS_ROLES_AUTHORITIES
185   add constraint PK_PUB_ROLES_AUTHORITY primary key (ID)
186   using index 
187   tablespace SCJD
188   pctfree 10
189   initrans 2
190   maxtrans 255
191   storage
192   (
193     initial 64K
194     minextents 1
195     maxextents unlimited
196   );
197 alter table SYS_ROLES_AUTHORITIES
198   add constraint FK_PUB_ROLES_AUTHORITIES_AU foreign key (AUTHORITY_ID)
199   references SYS_AUTHORITIES (AUTHORITY_ID);
200 alter table SYS_ROLES_AUTHORITIES
201   add constraint FK_PUB_ROLES_AUTHORITIES_ROLES foreign key (ROLE_ID)
202   references SYS_ROLES (ROLE_ID);
203 
204 prompt Creating SYS_USERS
205 create table SYS_USERS
206 (
207   USER_ID       VARCHAR2(32) not null,
208   USER_ACCOUNT  VARCHAR2(30),
209   USER_NAME     VARCHAR2(40),
210   USER_PASSWORD VARCHAR2(100),
211   USER_DESC     VARCHAR2(100),
212   ENABLED       NUMBER(1),
213   ISSYS         NUMBER(1),
214   USER_DEPT     VARCHAR2(20),
215   USER_DUTY     VARCHAR2(10),
216   SUB_SYSTEM    VARCHAR2(30)
217 )
218 tablespace SCJD
219   pctfree 10
220   initrans 1
221   maxtrans 255
222   storage
223   (
224     initial 64K
225     minextents 1
226     maxextents unlimited
227   );
228 comment on table SYS_USERS
229   is 用户表;
230 comment on column SYS_USERS.USER_PASSWORD
231   is 该密码是经加盐值加密的,格式为password{username}。 比如用户的密码为user,用户名为user,那么通过MD5进行加密的串为: user{user};
232 comment on column SYS_USERS.ISSYS
233   is 是否是超级用户;
234 comment on column SYS_USERS.USER_DEPT
235   is 所在单位;
236 comment on column SYS_USERS.USER_DUTY
237   is 经理或主任;
238 comment on column SYS_USERS.SUB_SYSTEM
239   is 该用户所负责的各子系统,可多个,中间用逗号分隔。(目前暂未用,作为保留字段);
240 alter table SYS_USERS
241   add constraint PK_PUB_USERS primary key (USER_ID)
242   using index 
243   tablespace SCJD
244   pctfree 10
245   initrans 2
246   maxtrans 255
247   storage
248   (
249     initial 64K
250     minextents 1
251     maxextents unlimited
252   );
253 
254 prompt Creating SYS_USERS_ROLES
255 create table SYS_USERS_ROLES
256 (
257   ID      NUMBER(13) not null,
258   USER_ID VARCHAR2(32),
259   ROLE_ID VARCHAR2(32),
260   ENABLED NUMBER(1)
261 )
262 tablespace SCJD
263   pctfree 10
264   initrans 1
265   maxtrans 255
266   storage
267   (
268     initial 64K
269     minextents 1
270     maxextents unlimited
271   );
272 comment on table SYS_USERS_ROLES
273   is 用户角色表;
274 alter table SYS_USERS_ROLES
275   add constraint PK_PUB_USERS_ROLES primary key (ID)
276   using index 
277   tablespace SCJD
278   pctfree 10
279   initrans 2
280   maxtrans 255
281   storage
282   (
283     initial 64K
284     minextents 1
285     maxextents unlimited
286   );
287 alter table SYS_USERS_ROLES
288   add constraint FK_USERS_ROLES_ROLES foreign key (ROLE_ID)
289   references SYS_ROLES (ROLE_ID);
290 alter table SYS_USERS_ROLES
291   add constraint FK_USERS_ROLES_USERS foreign key (USER_ID)
292   references SYS_USERS (USER_ID);
293 
294 prompt Disabling triggers for SYS_AUTHORITIES
295 alter table SYS_AUTHORITIES disable all triggers;
296 prompt Disabling triggers for SYS_RESOURCES
297 alter table SYS_RESOURCES disable all triggers;
298 prompt Disabling triggers for SYS_AUTHORITIES_RESOURCES
299 alter table SYS_AUTHORITIES_RESOURCES disable all triggers;
300 prompt Disabling triggers for SYS_ROLES
301 alter table SYS_ROLES disable all triggers;
302 prompt Disabling triggers for SYS_ROLES_AUTHORITIES
303 alter table SYS_ROLES_AUTHORITIES disable all triggers;
304 prompt Disabling triggers for SYS_USERS
305 alter table SYS_USERS disable all triggers;
306 prompt Disabling triggers for SYS_USERS_ROLES
307 alter table SYS_USERS_ROLES disable all triggers;
308 prompt Disabling foreign key constraints for SYS_AUTHORITIES_RESOURCES
309 alter table SYS_AUTHORITIES_RESOURCES disable constraint FK_PUB_AUTHORITIES_RE_AU;
310 alter table SYS_AUTHORITIES_RESOURCES disable constraint FK_PUB_AUTHORITIES_RE_RE;
311 prompt Disabling foreign key constraints for SYS_ROLES_AUTHORITIES
312 alter table SYS_ROLES_AUTHORITIES disable constraint FK_PUB_ROLES_AUTHORITIES_AU;
313 alter table SYS_ROLES_AUTHORITIES disable constraint FK_PUB_ROLES_AUTHORITIES_ROLES;
314 prompt Disabling foreign key constraints for SYS_USERS_ROLES
315 alter table SYS_USERS_ROLES disable constraint FK_USERS_ROLES_ROLES;
316 alter table SYS_USERS_ROLES disable constraint FK_USERS_ROLES_USERS;
317 prompt Deleting SYS_USERS_ROLES
318 delete from SYS_USERS_ROLES;
319 commit;
320 prompt Deleting SYS_USERS
321 delete from SYS_USERS;
322 commit;
323 prompt Deleting SYS_ROLES_AUTHORITIES
324 delete from SYS_ROLES_AUTHORITIES;
325 commit;
326 prompt Deleting SYS_ROLES
327 delete from SYS_ROLES;
328 commit;
329 prompt Deleting SYS_AUTHORITIES_RESOURCES
330 delete from SYS_AUTHORITIES_RESOURCES;
331 commit;
332 prompt Deleting SYS_RESOURCES
333 delete from SYS_RESOURCES;
334 commit;
335 prompt Deleting SYS_AUTHORITIES
336 delete from SYS_AUTHORITIES;
337 commit;
338 prompt Loading SYS_AUTHORITIES
339 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
340 values (1303910437484, AUTH_xxx, xxx, null, null, 01);
341 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
342 values (AUTH_LOGIN4, AUTH_LOGIN, 登录, 1, 0, 01);
343 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
344 values (AUTH_AFTERLOGINWELCOME5, AUTH_AFTERLOGINWELCOME, 登录后欢迎界面, 1, 0, 01);
345 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
346 values (AUTH_XTSZ_DEPT1, AUTH_XTSZ_DEPT, 单位设置, 1, 0, 01);
347 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
348 values (AUTH_XTSZ_USER2, AUTH_XTSZ_USER, 用户设置、横向查询, 1, 0, 01);
349 insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE)
350 values (AUTH_NODE_MGR3, AUTH_NODE_MGR, 节点管理、纵向查询, 1, 0, 01);
351 commit;
352 prompt 6 records loaded
353 prompt Loading SYS_RESOURCES
354 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
355 values (1303909883031, ff, ff, action, b.jsp, null, 1, 0, null);
356 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
357 values (1303909847687, ff1, ff1, action, b.jsp, null, 1, 0, null);
358 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
359 values (node_mgr3, node_mgr, 节点管理, url, /*/*/Tree.jsp, null, 1, 0, null);
360 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
361 values (login4, login, 登录, url, /login.jsp, null, 1, 0, null);
362 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
363 values (index5, index, 登录后欢迎页面, url, /index.jsp, null, 1, 0, null);
364 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
365 values (resources_mgr, resources_mgr, 资源管理, action, /managerResource, null, 1, 0, null);
366 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
367 values (horizontal_qry6, horizontal_qry, 横向查询, action, /horizontalQuery, null, 1, 0, null);
368 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
369 values (vertical_qry7, vertical_qry, 纵向查询, action, /verticalQuery, null, 1, 0, null);
370 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
371 values (dep_mgr1, dep_mgr, 单位管理, action, /UnitsManager, null, 1, 0, null);
372 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
373 values (user_mgr2, user_mgr, 用户管理, action, /managerUser, null, 1, 0, null);
374 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
375 values (authority_mgr, authority_mgr, 权限管理, action, /managerAuthority, null, 1, 0, null);
376 insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE)
377 values (role_mgr, role_mgr, 角色管理, action, /managerRole, null, null, null, null);
378 commit;
379 prompt 12 records loaded
380 prompt Loading SYS_AUTHORITIES_RESOURCES
381 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
382 values (1, AUTH_AFTERLOGINWELCOME5, index5, 1);
383 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
384 values (2, AUTH_LOGIN4, login4, 1);
385 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
386 values (3, AUTH_NODE_MGR3, node_mgr3, 1);
387 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
388 values (4, AUTH_XTSZ_DEPT1, dep_mgr1, 1);
389 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
390 values (5, AUTH_XTSZ_USER2, user_mgr2, 1);
391 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
392 values (7, AUTH_XTSZ_USER2, horizontal_qry6, 1);
393 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
394 values (8, AUTH_XTSZ_DEPT1, vertical_qry7, 1);
395 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
396 values (12, AUTH_XTSZ_USER2, role_mgr, 1);
397 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
398 values (10, AUTH_XTSZ_USER2, resources_mgr, 1);
399 insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED)
400 values (11, AUTH_XTSZ_USER2, authority_mgr, 1);
401 commit;
402 prompt 10 records loaded
403 prompt Loading SYS_ROLES
404 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
405 values (1303463518765, ROLE_dd1, dd1, 1, 0, 01);
406 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
407 values (1303463949640, ROLE_rr1, rr1, 1, 0, 02);
408 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
409 values (ROLE_PLATFORMADMIN1, ROLE_PLATFORMADMIN, 可管理整个平台的用户、单位设置。, 1, 1, 01);
410 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
411 values (ROLE_USER2, ROLE_USER, 普通用户, 1, 0, 01);
412 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
413 values (ROLE_LOGINTOWELCOME4, ROLE_LOGINTOWELCOME, 仅登录到欢迎界面!, 1, 0, 01);
414 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
415 values (ROLE_SYSADMIN3, ROLE_SYSADMIN, 可管理本系统的用户、单位设置。, 1, 0, 01);
416 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
417 values (ROLE_WORK, ROLE_WORK, 作业子系统的角色(试验), 1, 0, 02);
418 insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE)
419 values (ROLE_LOGIN, ROLE_LOGIN, 系统登录, 1, 0, 01);
420 commit;
421 prompt 8 records loaded
422 prompt Loading SYS_ROLES_AUTHORITIES
423 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
424 values (1, ROLE_LOGINTOWELCOME4, AUTH_AFTERLOGINWELCOME5, 1);
425 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
426 values (2, ROLE_PLATFORMADMIN1, AUTH_AFTERLOGINWELCOME5, 1);
427 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
428 values (3, ROLE_PLATFORMADMIN1, AUTH_LOGIN4, 1);
429 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
430 values (4, ROLE_PLATFORMADMIN1, AUTH_NODE_MGR3, 1);
431 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
432 values (5, ROLE_PLATFORMADMIN1, AUTH_XTSZ_DEPT1, 1);
433 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
434 values (6, ROLE_PLATFORMADMIN1, AUTH_XTSZ_USER2, 1);
435 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
436 values (7, ROLE_SYSADMIN3, AUTH_XTSZ_DEPT1, 1);
437 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
438 values (8, ROLE_SYSADMIN3, AUTH_XTSZ_USER2, 1);
439 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
440 values (9, ROLE_USER2, AUTH_LOGIN4, 1);
441 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
442 values (10, ROLE_LOGINTOWELCOME4, AUTH_LOGIN4, 1);
443 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
444 values (11, ROLE_USER2, AUTH_AFTERLOGINWELCOME5, 1);
445 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
446 values (1303463962718, 1303463949640, AUTH_LOGIN4, 1);
447 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
448 values (1303463972234, ROLE_WORK, AUTH_LOGIN4, 1);
449 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
450 values (1303463972235, ROLE_WORK, AUTH_AFTERLOGINWELCOME5, 1);
451 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
452 values (1303463972250, ROLE_WORK, AUTH_XTSZ_DEPT1, 1);
453 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
454 values (1303463972251, ROLE_WORK, AUTH_XTSZ_USER2, 1);
455 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
456 values (1303463972265, ROLE_WORK, AUTH_NODE_MGR3, 1);
457 insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED)
458 values (1303287600015, ROLE_LOGIN, AUTH_LOGIN4, 1);
459 commit;
460 prompt 18 records loaded
461 prompt Loading SYS_USERS
462 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
463 values (1304494573750, lxb, lxb, c7d3f4c857bc8c145d6e5d40c1bf23d9, null, 1, 0, 10011001, null, 01);
464 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
465 values (1304490737406, lxb, lxb, c7d3f4c857bc8c145d6e5d40c1bf23d9, null, 1, 0, 10011001, null, 01);
466 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
467 values (1304574079546, ddd, ddd, 0a4f6a961276619f7f91356bcba5a746, null, 0, 0, null, null, 01);
468 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
469 values (1304573363921, lxb, 卢小兵, 09eb37d219cfa835db40e5ab587f7082, 普通仅登录到欢迎界面!, 0, 0, 1001, null, 01);
470 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
471 values (1304573484515, lll, lll, 47acedc22cef8c3762c21a435e262d67, null, 1, 0, 1001, null, 01);
472 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
473 values (admin1, admin, 系统管理员, ceb4f32325eda6142bd65215f4c0f371, 超级系统管理员, 1, 1, 1001, null, 01);
474 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
475 values (user2, user, 普通用户, 47a733d60998c719cf3526ae7d106d13, 普通用户, 1, 0, 1001, null, 01);
476 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
477 values (sysUser3, sysUser, 系统设置维护, 8f0295328c34f8eedc2362e9f4a10b7e, 系统设置用户, 1, 0, 1001, null, 01);
478 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
479 values (lxb4, lxb, 卢小兵, c7d3f4c857bc8c145d6e5d40c1bf23d9, 普通仅登录到欢迎界面!, 1, 0, 1001, null, 01);
480 insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM)
481 values (1304566319625, lxb5, lx5, 1abe40ed6d0da1c834586e8ecef61fe7, null, 0, 0, 10011001, null, 01);
482 commit;
483 prompt 10 records loaded
484 prompt Loading SYS_USERS_ROLES
485 insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED)
486 values (1, admin1, ROLE_PLATFORMADMIN1, 1);
487 insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED)
488 values (2, sysUser3, ROLE_SYSADMIN3, 1);
489 insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED)
490 values (3, user2, ROLE_USER2, 1);
491 insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED)
492 values (4, lxb4, ROLE_LOGINTOWELCOME4, 1);
493 insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED)
494 values (5, 1304573484515, 1303463518765, null);
495 commit;
496 prompt 5 records loaded
497 prompt Enabling foreign key constraints for SYS_AUTHORITIES_RESOURCES
498 alter table SYS_AUTHORITIES_RESOURCES enable constraint FK_PUB_AUTHORITIES_RE_AU;
499 alter table SYS_AUTHORITIES_RESOURCES enable constraint FK_PUB_AUTHORITIES_RE_RE;
500 prompt Enabling foreign key constraints for SYS_ROLES_AUTHORITIES
501 alter table SYS_ROLES_AUTHORITIES enable constraint FK_PUB_ROLES_AUTHORITIES_AU;
502 alter table SYS_ROLES_AUTHORITIES enable constraint FK_PUB_ROLES_AUTHORITIES_ROLES;
503 prompt Enabling foreign key constraints for SYS_USERS_ROLES
504 alter table SYS_USERS_ROLES enable constraint FK_USERS_ROLES_ROLES;
505 alter table SYS_USERS_ROLES enable constraint FK_USERS_ROLES_USERS;
506 prompt Enabling triggers for SYS_AUTHORITIES
507 alter table SYS_AUTHORITIES enable all triggers;
508 prompt Enabling triggers for SYS_RESOURCES
509 alter table SYS_RESOURCES enable all triggers;
510 prompt Enabling triggers for SYS_AUTHORITIES_RESOURCES
511 alter table SYS_AUTHORITIES_RESOURCES enable all triggers;
512 prompt Enabling triggers for SYS_ROLES
513 alter table SYS_ROLES enable all triggers;
514 prompt Enabling triggers for SYS_ROLES_AUTHORITIES
515 alter table SYS_ROLES_AUTHORITIES enable all triggers;
516 prompt Enabling triggers for SYS_USERS
517 alter table SYS_USERS enable all triggers;
518 prompt Enabling triggers for SYS_USERS_ROLES
519 alter table SYS_USERS_ROLES enable all triggers;
520 set feedback on
521 set define on
522 prompt Done.
View Code

 

相关配置文件:

web.xml与第一种方法同。

applicationContext-security.xml:

 

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <b:beans xmlns="http://www.springframework.org/schema/security"
 4  xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5  xsi:schemaLocation="http://www.springframework.org/schema/beans 
 6  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 7     http://www.springframework.org/schema/security 
 8     http://www.springframework.org/schema/security/spring-security-3.0.xsd">
 9 
10 
11  <http auto-config="true" access-denied-page="/accessDenied.jsp">
12   <!-- 不要过滤图片等静态资源 -->
13   <intercept-url pattern="/**/*.jpg" filters="none" />
14   <intercept-url pattern="/**/*.png" filters="none" />
15   <intercept-url pattern="/**/*.gif" filters="none" />
16   <intercept-url pattern="/**/*.css" filters="none" />
17   <intercept-url pattern="/**/*.js" filters="none" />
18   <!-- 登录页面和忘记密码页面不过滤  -->
19   <intercept-url pattern="/login.jsp" filters="none" />
20   <intercept-url pattern="/jsp/forgotpassword.jsp"
21    filters="none" />  
22   
23   <form-login login-page="/login.jsp"
24    authentication-failure-url="/login.jsp?error=true"
25    default-target-url="/index.jsp" />
26 
27   <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) -->
28   <remember-me data-source-ref="dataSource" />
29   
30   <!-- 检测失效的sessionId,超时时定位到另外一个URL -->
31   <session-management invalid-session-url="/sessionTimeout.jsp" />
32   
33   
34   <!-- 增加一个自定义的filter,放在FILTER_SECURITY_INTERCEPTOR之前,
35   实现用户、角色、权限、资源的数据库管理。  -->
36   <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/> 
37   
38   
39  </http>
40  
41  
42  <!-- 一个自定义的filter,必须包含authenticationManager,
43   accessDecisionManager,securityMetadataSource三个属性。  -->
44  <b:bean id="myFilter" 
45   class="avatar.base.security.MyFilterSecurityInterceptor">
46   <b:property name="authenticationManager" 
47    ref="authenticationManager"/>
48   <b:property name="accessDecisionManager" 
49    ref="myAccessDecisionManager"/>
50   <b:property name="securityMetadataSource" 
51    ref="mySecurityMetadataSource"/>
52  </b:bean>
53  
54  
55 
56  <!-- 注意能够为authentication-manager 设置alias别名  -->
57  <authentication-manager alias="authenticationManager">
58   <authentication-provider user-service-ref="userDetailsManager">
59    <password-encoder ref="passwordEncoder">
60     <salt-source user-property="username" />
61    </password-encoder>
62   </authentication-provider>
63  </authentication-manager>
64 
65 
66  <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 -->
67  <b:bean id="myAccessDecisionManager"
68   class="avatar.base.security.MyAccessDecisionManager">
69  </b:bean>  
70 
71 
72  <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。 -->
73  <b:bean id="mySecurityMetadataSource"
74   class="avatar.base.security.MyInvocationSecurityMetadataSourceService">
75  </b:bean> 
76 
77 </b:beans>
View Code

 


applicationContext-service.xml:

 

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5  xmlns:util="http://www.springframework.org/schema/util"
 6  xmlns:jee="http://www.springframework.org/schema/jee" 
 7  xmlns:aop="http://www.springframework.org/schema/aop"
 8  xmlns:tx="http://www.springframework.org/schema/tx" 
 9  xmlns:context="http://www.springframework.org/schema/context"
10  xsi:schemaLocation="http://www.springframework.org/schema/beans
11  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
12    http://www.springframework.org/schema/aop 
13    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
14    http://www.springframework.org/schema/tx
15    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
16    http://www.springframework.org/schema/jee
17    http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
18    http://www.springframework.org/schema/context
19    http://www.springframework.org/schema/context/spring-context-3.0.xsd
20    http://www.springframework.org/schema/util 
21    http://www.springframework.org/schema/util/spring-util-3.0.xsd">
22 
23  
24  <!-- 定义上下文返回的消息的国际化。 -->
25  <bean id="messageSource"
26   class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
27   <property name="basename"
28    value="classpath:org/springframework/security/messages_zh_CN"/>
29  </bean>
30 
31  <!--
32   事件监听:实现了 ApplicationListener监听接口,
33   包括AuthenticationCredentialsNotFoundEvent 事件,
34   AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事
35   件。 -->
36  <bean
37   class="org.springframework.security.authentication.event.LoggerListener" />
38 
39  <!-- 用户的密码加密或解密 -->
40  <bean id="passwordEncoder"
41   class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
42 
43    
44  <!-- 用户详细信息管理:数据源、用户缓存(通过数据库管理用户、角色、权限、资源)。 -->
45  <bean id="userDetailsManager" class="avatar.base.security.MyUserDetailsService">
46   <property name="pubUsersHome" ref="pubUsersHome" />
47   <property name="pubAuthoritiesResourcesHome" ref="pubAuthoritiesResourcesHome" />
48   <property name="dataSource" ref="dataSource" />
49   <property name="userCache" ref="userCache" />
50  </bean>  
51  
52  <!-- 启用用户的缓存功能 -->
53  <bean id="userCache"
54   class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
55   <property name="cache" ref="userEhCache" />
56  </bean>
57  
58  <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
59   <property name="cacheName" value="userCache" />
60   <property name="cacheManager" ref="cacheManager" />
61  </bean>
62  
63  <bean id="cacheManager"
64   class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
65 
66 
67  <!-- spring security自带的与权限有关的数据读写Jdbc模板 -->
68  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
69   <property name="dataSource" ref="dataSource" />
70  </bean>
71 
72 </beans>
View Code

 


第三种方法扩展后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所具有的缺乏动态资源管理的硬伤(若是能够提供用户、角色、权限和资源的数据库管理,并且提供管理界面那实在是太完美了,可惜这两样一样都不能实现),又令国人用户爱恨交加。

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

 

Spring Security3的四种方法概述

标签:

原文地址:http://www.cnblogs.com/cangqiongbingchen/p/4531742.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!