标签:
那么在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‘);
可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过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>
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>
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>
令人欣喜的是,整个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>
这样一来,spring security3就会认为根本不需要对任何的URL或Action进行检测(注意上面代码中被注释掉的4条配置)。 哈哈,当时这个问题深深动摇了我对Spring security的信心,花费了这么多天的精力,却是这样的结果,当时就在考虑是否有更好的替代品。有点崩溃啊。 还好,深深地求知欲和征服欲让我坚持下来了。
哈哈,这算不算Spring
Security的一个Bug呢?没有任何的权限与资源的配置,就认为登录后的用户具有访问任何资源的权限,说起来有点可怕哈。
当然,当我将上述代码中被注释的4条配置放开后,Spring security奇迹般的恢复了活力。
接下来实现了jsp型URL的拦截之后,我又遇见了不能拦截action的情况,不过经过多次的配置和重启服务试验,终于发现,在配置Action与权限时,一定要在Action的路径前面加“/”斜杠,否则,Spring Security就会对该请求的URL熟视无睹,无视它的存在,即使你在Action的前后加上*号进行匹配也不会起任何作用,哈哈,不禁慨叹Spring Security的牛脾气。
顺便提一下子,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 }
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 }
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 }
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 }
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.
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>
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>
第三种方法扩展后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的Ioc、AOP等机制,横切开系统的业务组件,将通用的权限功能注入到业务组件内部,实现了通用功能和业务功能的无缝整合,但又保证了通用功能和业务功能的实现上的分离,省却了一部分工作量,这是其存在的最重要意义。
但又不可否认,Spring Security所具有的缺乏动态资源管理的硬伤(若是能够提供用户、角色、权限和资源的数据库管理,并且提供管理界面那实在是太完美了,可惜这两样一样都不能实现),又令国人用户爱恨交加。
该何去何从,就请自己做个选择吧!
标签:
原文地址:http://www.cnblogs.com/cangqiongbingchen/p/4531742.html