转载-Spring security
Sparta Yew 简约、职业、恒久
随笔 - 20, 文章 - 1, 评论 - 225, 引用 - 0
|
春天的故事-Spring Security3十五日研究
南朝《述异记》中记载,晋王质上山砍柴,见二童子下棋,未看完,斧柄已烂,下山回村,闻同代人都去世了,自已还未变老。 另有宋朝周敦颐在《暮春即事》中也有诗云:双双瓦雀行书案,点点杨花入砚池。闲坐小窗读周易,不知春去几多时。 上述古文或古诗中对于时间的论述最符合我现在的感受。已经整整十五日,对于Spring Serurity3的研究终于可以告一个段落了。 感觉这过往的十五日仿佛一瞬间而过,我沉浸在此中,一种强烈的求知愿望使我乐此不疲。到今天为止,终于将一种版本调通,可以正常使用了。 使用Spring Security3的四种方法概述 那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证; 二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。 三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器, 四是修改spring security的源代码,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService两个类。 说明一下,我目前调通的环境为: java1.6 + struts2.1.6 + spring3.0.1 + hibernate3.3.1 + spring security3.0.2 + oracle9i + weblogic10.3, 当然在进行spring security3的下面4种方法介绍之前,先假定SSH2的环境已经配置完毕,进入正常开发的过程,并且已经导入
第一种方法比较简单,可参考Spring Security自带的例子spring-security-samples-tutorial-3.0.2.RELEASE。 在spring-security-samples-tutorial-3.0.2.RELEASE的例子里,硬编码的配置请参见applicationContext-security.xml文件中的内容。 当然你最好运行起该例子来,感受一下,你可以直接将下载下来的解压缩后的文件夹中找到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语句。将用户和权限以数据库进行存储。
create table USERS( USERNAME VARCHAR2(50) not null, PASSWORD VARCHAR2(50) not null, ENABLED NUMBER(1) not null, USERNAMECN VARCHAR2(50), primary key( username ) )![]() create table AUTHORITIES( USERNAME VARCHAR2(50) not null, AUTHORITY VARCHAR2(50) not null )-- 外键使用户和权限相联。 Create/Recreate primary, unique and foreign key constraints alter table AUTHORITIES add constraint FK_AUTHORITIES_USERS foreign key (USERNAME) references USERS (USERNAME);
insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID) values ('lxb', 'c7d3f4c857bc8c145d6e5d40c1bf23d9', 1, '登录用户', 'AAAHmhAALAAAAAOAAA');![]() insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID) values ('admin', 'ceb4f32325eda6142bd65215f4c0f371', 1, '系统管理员', 'AAAHmhAALAAAAAPAAA');![]() insert into users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID) values ('user', '47a733d60998c719cf3526ae7d106d13', 1, '普通用户', 'AAAHmhAALAAAAAPAAB');再插入角色: insert into authorities (USERNAME, AUTHORITY, ROWID) values ('admin', 'ROLE_PLATFORMADMIN', 'AAAHmjAALAAAAAgAAA');![]() insert into authorities (USERNAME, AUTHORITY, ROWID) values ('admin', 'ROLE_SYSADMIN', 'AAAHmjAALAAAAAgAAB');![]() insert into authorities (USERNAME, AUTHORITY, ROWID) values ('lxb', 'ROLE_LOGIN', 'AAAHmjAALAAAAAeAAA');![]() insert into authorities (USERNAME, AUTHORITY, ROWID) values ('lxb', 'ROLE_LOGINTOWELCOME', 'AAAHmjAALAAAAAeAAB');![]() insert into authorities (USERNAME, AUTHORITY, ROWID) values ('user', 'ROLE_USER', 'AAAHmjAALAAAAAgAAC');
可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过MD5进行加密过的,并且以用户名做为了盐值,最后就成为32位数字这个样子,这个你可以参见下面applicationContext-Security.xml中的password-encoder和salt-source的配置就会明白。 我们在试验过程中,通常喜欢先将几个常用的用户及密码插入数据库进行试验,这种情况下如何得到该用户的密码密文呢? user369{user} 拿上述的字串拷贝到 http://www.51240.com/md5jiami/ 网页上的输入框里,点击加密按钮,下面即可生成32位数字的密码密文。 哈哈,屡试不爽啊。这个方法要谨慎使用,一般人我不告诉他。
将权限及资源(URL或Action)的关系配置在xml文件中,并且配置与Spring Security3相关的其他配置: 1、applicationContext-Security.xml代码:
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">![]() <http auto-config="true" access-denied-page="/accessDenied.jsp"> <!-- 不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。 --> <intercept-url pattern="/**/*.jpg" filters="none" /> <intercept-url pattern="/**/*.png" filters="none" /> <intercept-url pattern="/**/*.gif" filters="none" /> <intercept-url pattern="/**/*.css" filters="none" /> <intercept-url pattern="/**/*.js" filters="none" /> <!-- 登录页面和忘记密码页面不过滤 --> <intercept-url pattern="/login.jsp" filters="none" /> <intercept-url pattern="/jsp/forgotpassword.jsp" filters="none" /> ![]() <!-- 下面是对Action配置。表示具有访问/unitsManager资源的用户必须具有ROLE_PLATFORMADMIN的权限。 当用户登录时,SS3将用户的所有权限从数据库中提取出来,形成列表。 当用户访问该资源时,SS3将 登录用户的权限列表提出来跟下面配置的权限进行比对,若有,则允许访问,若没有,则给出AccessDeniedException。--> <intercept-url pattern="/unitsManager" access="ROLE_PLATFORMADMIN" /> <intercept-url pattern="/usersManager" access="ROLE_PLATFORMADMIN" />![]() <intercept-url pattern="/horizontalQuery" access="ROLE_PLATFORMADMIN" /> <intercept-url pattern="/verticalQuery" access="ROLE_PLATFORMADMIN" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" />![]() <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) --> <remember-me data-source-ref="dataSource" /> <!-- 检测失效的sessionId,超时时定位到另外一个URL --> <session-management invalid-session-url="/sessionTimeout.jsp" /> </http>![]() <!-- 注意能够为authentication-manager 设置alias别名 --> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userDetailsManager"> <password-encoder ref="passwordEncoder"> <!-- 用户名做为盐值 --> <salt-source user-property="username" /> </password-encoder> </authentication-provider> </authentication-manager>![]() </b:beans>2、applicationContext.service.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- 定义上下文返回的消息的国际化。 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/> </bean>![]() <!-- 事件监听:实现了 ApplicationListener监听接口,包括AuthenticationCredentialsNotFoundEvent 事件, AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事件 --> <bean class="org.springframework.security.authentication.event.LoggerListener" />![]() <!-- 用户的密码加密或解密 --> <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />![]() ![]() <!-- 用户详细信息管理 : 数据源、用户缓存、启用用户组功能。 --> <bean id="userDetailsManager" class="org.springframework.security.provisioning.JdbcUserDetailsManager"> <property name="dataSource" ref="dataSource" /> <property name="userCache" ref="userCache" /> </bean> <bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> <property name="cache" ref="userEhCache" /> </bean> <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheName" value="userCache" /> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- 缓存用户管理 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> ![]() <!-- spring security自带的与权限有关的数据读写Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>![]() </beans>3、web.xml:
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">![]() ![]() <!-- 设置log4j存放Log文件位置(通过spring统一进行管理) --> <context-param> <param-name>webAppRootKey</param-name> <param-value>log.root</param-value> </context-param>![]() <!-- 加载log4j的配置文件 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:/log4j.properties</param-value> </context-param>![]() <!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond--> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60000</param-value> </context-param>![]() <!--Spring用于log4j初始化的监听器--> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener>![]() <!-- 加载Spring XML配置文件,Spring安全配置及各类资源文件,暂不加 /WEB-INF/applicationContext-security.xml, --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/applicationContext*.xml, classpath*:applicationContext.xml </param-value> </context-param>![]() <!--spring监听器的配置,用于在启动Web容器时,自动装配ApplicationContext的配置信息--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>![]() <!-- 使用Spring中的过滤器解决在请求和应答中的中文乱码问题 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>gbk</param-value> </init-param> <init-param> <!--强制转换编码(request和response均适用) --> <param-name>ForceEncoding</param-name> <param-value>true</param-value> </init-param> </filter>![]() <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>![]() <!-- Spring Secutiry3.0.2的过滤器链配置 --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter>![]() <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>![]() <!-- 配置Struts2的FilterDispathcer的Filter --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter>![]() <!-- struts2用以处理用户Web请求的路径模式--> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 避免乱码问题 --> <filter> <filter-name>struts-cleanup</filter-name> <filter-class> org.apache.struts2.dispatcher.ActionContextCleanUp </filter-class> </filter> <filter-mapping> <filter-name>struts-cleanup</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring刷新Interceptor防止内存泄漏 --> <listener> <listener-class> org.springframework.web.util.IntrospectorCleanupListener </listener-class> </listener> ![]() <!-- 设置session 超时时间为20分钟 --> <session-config> <session-timeout>20</session-timeout> </session-config>![]() <!--系统欢迎页面--> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>![]() </web-app>
第二种方法中遇见的问题 当然,首次使用Spring serutiry,在整合的过程中,我还是遇见了不少问题,当然有些问题比如找不到类呀,包呀,和框架的整合呀等问题不作为谈论的重点。主要还是探讨Spring Security的配置和注意事项的问题。 我在其中碰到的对我印象最深的问题是,当完全配置好之后,重启Web服务器,却发现Spring Security不能拦截任何的URL了,这使我感到惊诧,因为在去年时,我已经将该框架搭建完成,在当时正是使用的该种方法,并且在试验是否能够拦截jsp文件时进行了确认是没有问题的。 接下来我又整理了一下applicationContext-security.xml的文件才发现, 除了不需要进行检测的图片及登录页面之外,没有对任何的资源和权限之间的对应关系进行配置,参见下面的代码: <http auto-config="true" access-denied-page="/accessDenied.jsp"> <!-- 不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。 --> <intercept-url pattern="/**/*.jpg" filters="none" /> <intercept-url pattern="/**/*.png" filters="none" /> <intercept-url pattern="/**/*.gif" filters="none" /> <intercept-url pattern="/**/*.css" filters="none" /> <intercept-url pattern="/**/*.js" filters="none" /> <!-- 登录页面和忘记密码页面不过滤 --> <intercept-url pattern="/login.jsp" filters="none" /> <intercept-url pattern="/jsp/forgotpassword.jsp" filters="none" /> ![]() <!-- 下面是对Struts2的Action请求时的配置。注意在前面加/,否则不会被SS3进行拦截验证。 表示具有访问/unitsManager资源的用户必须具有ROLE_PLATFORMADMIN的权限。 当用户登录时,SS3将用户的所有权限从数据库中提取出来,形成列表。 当用户访问该资源时, SS3将登录用户的权限列表提出来跟下面配置的权限进行比对,若有,则允许访问,若没有, 则给出AccessDeniedException。 <intercept-url pattern="/unitsManager" access="ROLE_PLATFORMADMIN" /> <intercept-url pattern="/usersManager" access="ROLE_PLATFORMADMIN" /> <intercept-url pattern="/horizontalQuery" access="ROLE_PLATFORMADMIN" /> <intercept-url pattern="/verticalQuery" access="ROLE_PLATFORMADMIN" /> --> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" />![]() <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) --> <remember-me data-source-ref="dataSource" /> <!-- 检测失效的sessionId,超时时定位到另外一个URL --> <session-management invalid-session-url="/sessionTimeout.jsp" /> </http> 这样一来,spring security3就会认为根本不需要对任何的URL或Action进行检测(注意上面代码中被注释掉的4条配置)。 哈哈,当时这个问题深深动摇了我对Spring security的信心,花费了这么多天的精力,却是这样的结果,当时就在考虑是否有更好的替代品。有点崩溃啊。 还好,深深地求知欲和征服欲让我坚持下来了。 当然,当我将上述代码中被注释的4条配置放开后,Spring security奇迹般的恢复了活力。 接下来实现了jsp型URL的拦截之后,我又遇见了不能拦截action的情况,不过经过多次的配置和重启服务试验,终于发现,在配置Action与权限时,一定要在Action的路径前面加“/”斜杠,否则,Spring Security就会对该请求的URL熟视无睹,无视它的存在,即使你在Action的前后加上*号进行匹配也不会起任何作用,哈哈,不禁慨叹Spring Security的牛脾气。
顺便提一下子,Spring Security3需要配置的过滤器是双重的,首先在web.xml中配置一个过滤器代理,参见上述web.xml中的springSecurityFilterChain配置。 那么这第二重过滤器的配置,就是那些所谓的过滤器链,分别包括“记住我”、“登录”、“注销”、“url访问”等的过滤器,这个过滤器依顺序排开,形成一个过滤链条。具体拦截我们明细Url的是一个叫做FilterInterCeptor的伙计,我认为这个家伙是在整个过滤器链条中是最重要的一个,因为我们登录系统之后,要访问的任何资源都必须经得他的同意。 那么这第二重链条就设置在applicationContext-security.xml文件中的<http>元素下面。
第三种方法 当然,spring security3毕竟是西方国家的东西,以英文为主,使用习惯和文化的差异共存,况且为了适应大多数Web应用的权限管理,作者将Spring Security3打造的精简而灵活。精简指Spring Security3对用户和权限的表设计的非常简单,并且没有采用数据库来管理资源(URL)。这样的话,对于我们国人用户来说,是个很大的遗憾,这个遗憾甚至能够影响到我们对安全框架的选型。你想啊,在国内大多数项目中,均设置了比较复杂的权限控制,一般就会涉及到用户、角色、权限、资源4张表,若要加上4张表之间的对应关系表3张,得有7张表才行。 得7张表才行,但是Spring Security3才给我们提供了2张最简洁的表,这足以不能完成国人用户的项目应用。那么在对Spring Security3一无所知的情况下, 还好,Spring Security3提供了灵活的扩展方法。具体应该扩展哪些类呢? 或者到底Spring Security3工作的流程如何,你不妨参看下面一篇文章,就会获得 还有一个地址很有价值, http://wenku.baidu.com/view/4ec7e324ccbff121dd368364.html ,我就参考着上面的介绍扩展了4个类。 不过我得提一下,原文的作者为了考验你的耐性和自信心,故意在代码里面卖了几点小小的关子,因此若是完全按照作者的原文代码装配起来的权限系统,是不会那么顺利地工作的,天下似乎真是没有不花费力气的午餐!在装配完成后,我也是经过九九八十一难的折磨,在用户、角色、权限、资源的 并扩展了User类以增加其相关的各类其他信息(如Email,职务,所在单位id等)。
/* * @(#) MyFilterSecurityInterceptor.java 2011-3-23 上午07:53:03 * * Copyright 2011 by Sparta */![]() package avatar.base.security;![]() import java.io.IOException;![]() import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;![]() import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;![]() /** * 该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。 * securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。 * 该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中, * 供Spring Security使用,用于权限校验。 * @author sparta 11/3/29 * */![]() public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter{ ![]() private FilterInvocationSecurityMetadataSource securityMetadataSource; public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{ FilterInvocation fi = new FilterInvocation( request, response, chain ); invoke(fi); } public FilterInvocationSecurityMetadataSource getSecurityMetadataSource(){ return this.securityMetadataSource; } public Class<? extends Object> getSecureObjectClass(){ return FilterInvocation.class; }![]() public void invoke( FilterInvocation fi ) throws IOException, ServletException{ InterceptorStatusToken token = super.beforeInvocation(fi); try{ fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); }finally{ super.afterInvocation(token, null); } } @Override public SecurityMetadataSource obtainSecurityMetadataSource(){ return this.securityMetadataSource; } public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource){ this.securityMetadataSource = securityMetadataSource; } public void destroy(){ } public void init( FilterConfig filterconfig ) throws ServletException{ } }![]() ![]() /* * @(#) MyInvocationSecurityMetadataSourceService.java 2011-3-23 下午02:58:29 * * Copyright 2011 by Sparta */![]() package avatar.base.security;![]() import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map;![]() import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.AntUrlPathMatcher; import org.springframework.security.web.util.UrlMatcher; import org.springframework.stereotype.Service;![]() import avatar.base.security.dao.PubAuthoritiesResourcesHome;![]() /** * 最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。 此类在初始化时,应该取到所有资源及其对应角色的定义。 * */ @Service public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {![]() @Autowired private PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome;![]() private UrlMatcher urlMatcher = new AntUrlPathMatcher();![]() private static Map<String, Collection<ConfigAttribute>> resourceMap = null;![]() public MyInvocationSecurityMetadataSourceService() { loadResourceDefine(); }![]() private void loadResourceDefine() { ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:applicationContext.xml");![]() SessionFactory sessionFactory = (SessionFactory) context .getBean("sessionFactory");![]() Session session = sessionFactory.openSession();![]() String username = ""; String sql = "";![]() // 在Web服务器启动时,提取系统中的所有权限。 sql = "select authority_name from pub_authorities";![]() List<String> query = session.createSQLQuery(sql).list();![]() /* * 应当是资源为key, 权限为value。 资源通常为url, 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。 * sparta */ resourceMap = new HashMap<String, Collection<ConfigAttribute>>();![]() for (String auth : query) { ConfigAttribute ca = new SecurityConfig(auth);![]() List<String> query1 = session .createSQLQuery( "select b.resource_string " + "from Pub_Authorities_Resources a, Pub_Resources b, " + "Pub_authorities c where a.resource_id = b.resource_id " + "and a.authority_id=c.authority_id and c.Authority_name='" + auth + "'").list();![]() for (String res : query1) { String url = res; /* * 判断资源文件和权限的对应关系,如果已经存在相关的资源url,则要通过该url为key提取出权限集合,将权限增加到权限集合中。 * sparta */ if (resourceMap.containsKey(url)) {![]() Collection<ConfigAttribute> value = resourceMap.get(url); value.add(ca); resourceMap.put(url, value); } else { Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); atts.add(ca); resourceMap.put(url, atts); }![]() }![]() }![]() }![]() @Override public Collection<ConfigAttribute> getAllConfigAttributes() {![]() return null; }![]() // 根据URL,找到相关的权限配置。 @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {![]() // object 是一个URL,被用户请求的url。 String url = ((FilterInvocation) object).getRequestUrl(); int firstQuestionMarkIndex = url.indexOf("?");![]() if (firstQuestionMarkIndex != -1) { url = url.substring(0, firstQuestionMarkIndex); }![]() Iterator<String> ite = resourceMap.keySet().iterator();![]() while (ite.hasNext()) { String resURL = ite.next(); if (urlMatcher.pathMatchesUrl(url, resURL)) {![]() return resourceMap.get(resURL); } }![]() return null; }![]() @Override public boolean supports(Class<?> arg0) {![]() return true; }![]() }![]() ![]() /* * @(#) MyUserDetailsService.java 2011-3-23 上午09:04:31 * * Copyright 2011 by Sparta */![]() package avatar.base.security;![]() ![]() import java.util.ArrayList; import java.util.Collection;![]() ![]() import javax.sql.DataSource;![]() ![]() import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserCache; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service;![]() import avatar.base.security.dao.PubAuthoritiesResourcesHome; import avatar.base.security.dao.PubUsersHome;![]() ![]() /** *该类的主要作用是为Spring Security提供一个经过用户认证后的UserDetails。 *该UserDetails包括用户名、密码、是否可用、是否过期等信息。 *sparta 11/3/29 */ @Service public class MyUserDetailsService implements UserDetailsService {![]() @Autowired private PubUsersHome pubUsersHome; @Autowired private PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome; @Autowired private DataSource dataSource; @Autowired private UserCache userCache;![]() @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); //得到用户的权限 auths = pubUsersHome.loadUserAuthoritiesByName( username ); String password = null; //取得用户的密码 password = pubUsersHome.getPasswordByUsername( username ); return new User( username, password, true, "", true, true, true, auths); } //set PubUsersHome public void setPubUsersHome( PubUsersHome pubUsersHome ){ this.pubUsersHome = pubUsersHome; } public PubUsersHome getPubUsersHome(){ return pubUsersHome; } //set PubAuthoritiesResourcesHome public void setPubAuthoritiesResourcesHome( PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome ){ this.pubAuthoritiesResourcesHome = pubAuthoritiesResourcesHome; } public PubAuthoritiesResourcesHome getPubAuthoritiesResourcesHome(){ return pubAuthoritiesResourcesHome; } //set DataSource public void setDataSource( DataSource dataSource ){ this.dataSource = dataSource; } public DataSource getDataSource(){ return dataSource; } //设置用户缓存功能。 public void setUserCache(UserCache userCache) { this.userCache = userCache; } public UserCache getUserCache(){ return this.userCache; } }![]() /* * @(#) MyAccessDecisionManager.java 2011-3-23 下午04:41:12 * * Copyright 2011 by Sparta */![]() package avatar.base.security;![]() import java.util.Collection; import java.util.Iterator;![]() import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority;![]() /** *AccessdecisionManager在Spring security中是很重要的。 * *在验证部分简略提过了,所有的Authentication实现需要保存在一个GrantedAuthority对象数组中。 *这就是赋予给主体的权限。 GrantedAuthority对象通过AuthenticationManager *保存到 Authentication对象里,然后从AccessDecisionManager读出来,进行授权判断。 * *Spring Security提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。 *一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。 *这个 AccessDecisionManager 被AbstractSecurityInterceptor调用, *它用来作最终访问控制的决定。 这个AccessDecisionManager接口包含三个方法: * void decide(Authentication authentication, Object secureObject, List<ConfigAttributeDefinition> config) throws AccessDeniedException; boolean supports(ConfigAttribute attribute); boolean supports(Class clazz); 从第一个方法可以看出来,AccessDecisionManager使用方法参数传递所有信息,这好像在认证评估时进行决定。 特别是,在真实的安全方法期望调用的时候,传递安全Object启用那些参数。 比如,让我们假设安全对象是一个MethodInvocation。 很容易为任何Customer参数查询MethodInvocation, 然后在AccessDecisionManager里实现一些有序的安全逻辑,来确认主体是否允许在那个客户上操作。 如果访问被拒绝,实现将抛出一个AccessDeniedException异常。![]() 这个 supports(ConfigAttribute) 方法在启动的时候被 AbstractSecurityInterceptor调用,来决定AccessDecisionManager 是否可以执行传递ConfigAttribute。 supports(Class)方法被安全拦截器实现调用, 包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。 */ public class MyAccessDecisionManager implements AccessDecisionManager { public void decide( Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException{ if( configAttributes == null ) { return ; } Iterator<ConfigAttribute> ite = configAttributes.iterator(); while( ite.hasNext()){ ConfigAttribute ca = ite.next(); String needRole = ((SecurityConfig)ca).getAttribute(); //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。 for( GrantedAuthority ga: authentication.getAuthorities()){ if(needRole.trim().equals(ga.getAuthority().trim())){![]() return; } } } throw new AccessDeniedException(""); } public boolean supports( ConfigAttribute attribute ){ return true;![]() } public boolean supports(Class<?> clazz){ return true;![]() } ![]() }
prompt PL/SQL Developer import file prompt Created on 2011年6月1日 by Administrator set feedback off set define off prompt Creating SYS_AUTHORITIES![]() create table SYS_AUTHORITIES ( AUTHORITY_ID VARCHAR2(32) not null, AUTHORITY_NAME VARCHAR2(40), AUTHORITY_DESC VARCHAR2(100), ENABLED NUMBER(1), ISSYS NUMBER(1), MODULE VARCHAR2(4) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_AUTHORITIES is '权限表'; comment on column SYS_AUTHORITIES.MODULE is '所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。'; alter table SYS_AUTHORITIES add constraint PK_PUB_AUTHORITIES primary key (AUTHORITY_ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited );![]() prompt Creating SYS_RESOURCES![]() create table SYS_RESOURCES ( RESOURCE_ID VARCHAR2(32) not null, RESOURCE_NAME VARCHAR2(100), RESOURCE_DESC VARCHAR2(100), RESOURCE_TYPE VARCHAR2(40), RESOURCE_STRING VARCHAR2(200), PRIORITY NUMBER(1), ENABLED NUMBER(1), ISSYS NUMBER(1), MODULE VARCHAR2(4) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_RESOURCES is '资源表'; comment on column SYS_RESOURCES.PRIORITY is '(暂不用,保留)'; comment on column SYS_RESOURCES.MODULE is '所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。 (暂不用,保留)'; alter table SYS_RESOURCES add constraint PK_PUB_RESOURCES primary key (RESOURCE_ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited );![]() prompt Creating SYS_AUTHORITIES_RESOURCES![]() create table SYS_AUTHORITIES_RESOURCES ( ID NUMBER(13) not null, AUTHORITY_ID VARCHAR2(32), RESOURCE_ID VARCHAR2(32), ENABLED NUMBER(1) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_AUTHORITIES_RESOURCES is '权限资源表'; alter table SYS_AUTHORITIES_RESOURCES add constraint PK_PUB_AUTHORITIES_RE primary key (ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); alter table SYS_AUTHORITIES_RESOURCES add constraint FK_PUB_AUTHORITIES_RE_AU foreign key (AUTHORITY_ID) references SYS_AUTHORITIES (AUTHORITY_ID); alter table SYS_AUTHORITIES_RESOURCES add constraint FK_PUB_AUTHORITIES_RE_RE foreign key (RESOURCE_ID) references SYS_RESOURCES (RESOURCE_ID);![]() prompt Creating SYS_ROLES![]() create table SYS_ROLES ( ROLE_ID VARCHAR2(32) not null, ROLE_NAME VARCHAR2(40), ROLE_DESC VARCHAR2(100), ENABLED NUMBER(1), ISSYS NUMBER(1), MODULE VARCHAR2(4) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_ROLES is '角色表'; comment on column SYS_ROLES.MODULE is '所属的子系统,比如平台里面包括10个系统,分别为成本、作业、集输等。'; alter table SYS_ROLES add constraint PK_PUB_ROLES primary key (ROLE_ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited );![]() prompt Creating SYS_ROLES_AUTHORITIES![]() create table SYS_ROLES_AUTHORITIES ( ID NUMBER(13) not null, ROLE_ID VARCHAR2(32), AUTHORITY_ID VARCHAR2(32), ENABLED NUMBER(1) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_ROLES_AUTHORITIES is '角色权限表'; alter table SYS_ROLES_AUTHORITIES add constraint PK_PUB_ROLES_AUTHORITY primary key (ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); alter table SYS_ROLES_AUTHORITIES add constraint FK_PUB_ROLES_AUTHORITIES_AU foreign key (AUTHORITY_ID) references SYS_AUTHORITIES (AUTHORITY_ID); alter table SYS_ROLES_AUTHORITIES add constraint FK_PUB_ROLES_AUTHORITIES_ROLES foreign key (ROLE_ID) references SYS_ROLES (ROLE_ID);![]() prompt Creating SYS_USERS![]() create table SYS_USERS ( USER_ID VARCHAR2(32) not null, USER_ACCOUNT VARCHAR2(30), USER_NAME VARCHAR2(40), USER_PASSWORD VARCHAR2(100), USER_DESC VARCHAR2(100), ENABLED NUMBER(1), ISSYS NUMBER(1), USER_DEPT VARCHAR2(20), USER_DUTY VARCHAR2(10), SUB_SYSTEM VARCHAR2(30) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_USERS is '用户表'; comment on column SYS_USERS.USER_PASSWORD is '该密码是经加盐值加密的,格式为password{username}。 比如用户的密码为user,用户名为user,那么通过MD5进行加密的串为: user{user}'; comment on column SYS_USERS.ISSYS is '是否是超级用户'; comment on column SYS_USERS.USER_DEPT is '所在单位'; comment on column SYS_USERS.USER_DUTY is '经理或主任'; comment on column SYS_USERS.SUB_SYSTEM is '该用户所负责的各子系统,可多个,中间用逗号分隔。(目前暂未用,作为保留字段)'; alter table SYS_USERS add constraint PK_PUB_USERS primary key (USER_ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited );![]() prompt Creating SYS_USERS_ROLES![]() create table SYS_USERS_ROLES ( ID NUMBER(13) not null, USER_ID VARCHAR2(32), ROLE_ID VARCHAR2(32), ENABLED NUMBER(1) ) tablespace SCJD pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); comment on table SYS_USERS_ROLES is '用户角色表'; alter table SYS_USERS_ROLES add constraint PK_PUB_USERS_ROLES primary key (ID) using index tablespace SCJD pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited ); alter table SYS_USERS_ROLES add constraint FK_USERS_ROLES_ROLES foreign key (ROLE_ID) references SYS_ROLES (ROLE_ID); alter table SYS_USERS_ROLES add constraint FK_USERS_ROLES_USERS foreign key (USER_ID) references SYS_USERS (USER_ID);![]() prompt Disabling triggers for SYS_AUTHORITIES![]() alter table SYS_AUTHORITIES disable all triggers; prompt Disabling triggers for SYS_RESOURCES![]() alter table SYS_RESOURCES disable all triggers; prompt Disabling triggers for SYS_AUTHORITIES_RESOURCES![]() alter table SYS_AUTHORITIES_RESOURCES disable all triggers; prompt Disabling triggers for SYS_ROLES![]() alter table SYS_ROLES disable all triggers; prompt Disabling triggers for SYS_ROLES_AUTHORITIES![]() alter table SYS_ROLES_AUTHORITIES disable all triggers; prompt Disabling triggers for SYS_USERS![]() alter table SYS_USERS disable all triggers; prompt Disabling triggers for SYS_USERS_ROLES![]() alter table SYS_USERS_ROLES disable all triggers; prompt Disabling foreign key constraints for SYS_AUTHORITIES_RESOURCES![]() alter table SYS_AUTHORITIES_RESOURCES disable constraint FK_PUB_AUTHORITIES_RE_AU; alter table SYS_AUTHORITIES_RESOURCES disable constraint FK_PUB_AUTHORITIES_RE_RE; prompt Disabling foreign key constraints for SYS_ROLES_AUTHORITIES![]() alter table SYS_ROLES_AUTHORITIES disable constraint FK_PUB_ROLES_AUTHORITIES_AU; alter table SYS_ROLES_AUTHORITIES disable constraint FK_PUB_ROLES_AUTHORITIES_ROLES; prompt Disabling foreign key constraints for SYS_USERS_ROLES![]() alter table SYS_USERS_ROLES disable constraint FK_USERS_ROLES_ROLES; alter table SYS_USERS_ROLES disable constraint FK_USERS_ROLES_USERS; prompt Deleting SYS_USERS_ROLES![]() delete from SYS_USERS_ROLES; commit; prompt Deleting SYS_USERS![]() delete from SYS_USERS; commit; prompt Deleting SYS_ROLES_AUTHORITIES![]() delete from SYS_ROLES_AUTHORITIES; commit; prompt Deleting SYS_ROLES![]() delete from SYS_ROLES; commit; prompt Deleting SYS_AUTHORITIES_RESOURCES![]() delete from SYS_AUTHORITIES_RESOURCES; commit; prompt Deleting SYS_RESOURCES![]() delete from SYS_RESOURCES; commit; prompt Deleting SYS_AUTHORITIES![]() delete from SYS_AUTHORITIES; commit; prompt Loading SYS_AUTHORITIES![]() insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('1303910437484', 'AUTH_xxx', 'xxx', null, null, '01'); insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('AUTH_LOGIN4', 'AUTH_LOGIN', '登录', 1, 0, '01'); insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('AUTH_AFTERLOGINWELCOME5', 'AUTH_AFTERLOGINWELCOME', '登录后欢迎界面', 1, 0, '01'); insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('AUTH_XTSZ_DEPT1', 'AUTH_XTSZ_DEPT', '单位设置', 1, 0, '01'); insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('AUTH_XTSZ_USER2', 'AUTH_XTSZ_USER', '用户设置、横向查询', 1, 0, '01'); insert into SYS_AUTHORITIES (AUTHORITY_ID, AUTHORITY_NAME, AUTHORITY_DESC, ENABLED, ISSYS, MODULE) values ('AUTH_NODE_MGR3', 'AUTH_NODE_MGR', '节点管理、纵向查询', 1, 0, '01'); commit; prompt 6 records loaded prompt Loading SYS_RESOURCES![]() insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('1303909883031', 'ff', 'ff', 'action', 'b.jsp', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('1303909847687', 'ff1', 'ff1', 'action', 'b.jsp', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('node_mgr3', 'node_mgr', '节点管理', 'url', '/*/*/Tree.jsp', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('login4', 'login', '登录', 'url', '/login.jsp', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('index5', 'index', '登录后欢迎页面', 'url', '/index.jsp', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('resources_mgr', 'resources_mgr', '资源管理', 'action', '/managerResource', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('horizontal_qry6', 'horizontal_qry', '横向查询', 'action', '/horizontalQuery', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('vertical_qry7', 'vertical_qry', '纵向查询', 'action', '/verticalQuery', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('dep_mgr1', 'dep_mgr', '单位管理', 'action', '/UnitsManager', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('user_mgr2', 'user_mgr', '用户管理', 'action', '/managerUser', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('authority_mgr', 'authority_mgr', '权限管理', 'action', '/managerAuthority', null, 1, 0, null); insert into SYS_RESOURCES (RESOURCE_ID, RESOURCE_NAME, RESOURCE_DESC, RESOURCE_TYPE, RESOURCE_STRING, PRIORITY, ENABLED, ISSYS, MODULE) values ('role_mgr', 'role_mgr', '角色管理', 'action', '/managerRole', null, null, null, null); commit; prompt 12 records loaded prompt Loading SYS_AUTHORITIES_RESOURCES![]() insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (1, 'AUTH_AFTERLOGINWELCOME5', 'index5', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (2, 'AUTH_LOGIN4', 'login4', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (3, 'AUTH_NODE_MGR3', 'node_mgr3', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (4, 'AUTH_XTSZ_DEPT1', 'dep_mgr1', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (5, 'AUTH_XTSZ_USER2', 'user_mgr2', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (7, 'AUTH_XTSZ_USER2', 'horizontal_qry6', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (8, 'AUTH_XTSZ_DEPT1', 'vertical_qry7', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (12, 'AUTH_XTSZ_USER2', 'role_mgr', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (10, 'AUTH_XTSZ_USER2', 'resources_mgr', 1); insert into SYS_AUTHORITIES_RESOURCES (ID, AUTHORITY_ID, RESOURCE_ID, ENABLED) values (11, 'AUTH_XTSZ_USER2', 'authority_mgr', 1); commit; prompt 10 records loaded prompt Loading SYS_ROLES![]() insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('1303463518765', 'ROLE_dd1', 'dd1', 1, 0, '01'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('1303463949640', 'ROLE_rr1', 'rr1', 1, 0, '02'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_PLATFORMADMIN1', 'ROLE_PLATFORMADMIN', '可管理整个平台的用户、单位设置。', 1, 1, '01'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_USER2', 'ROLE_USER', '普通用户', 1, 0, '01'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_LOGINTOWELCOME4', 'ROLE_LOGINTOWELCOME', '仅登录到欢迎界面!', 1, 0, '01'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_SYSADMIN3', 'ROLE_SYSADMIN', '可管理本系统的用户、单位设置。', 1, 0, '01'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_WORK', 'ROLE_WORK', '作业子系统的角色(试验)', 1, 0, '02'); insert into SYS_ROLES (ROLE_ID, ROLE_NAME, ROLE_DESC, ENABLED, ISSYS, MODULE) values ('ROLE_LOGIN', 'ROLE_LOGIN', '系统登录', 1, 0, '01'); commit; prompt 8 records loaded prompt Loading SYS_ROLES_AUTHORITIES![]() insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1, 'ROLE_LOGINTOWELCOME4', 'AUTH_AFTERLOGINWELCOME5', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (2, 'ROLE_PLATFORMADMIN1', 'AUTH_AFTERLOGINWELCOME5', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (3, 'ROLE_PLATFORMADMIN1', 'AUTH_LOGIN4', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (4, 'ROLE_PLATFORMADMIN1', 'AUTH_NODE_MGR3', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (5, 'ROLE_PLATFORMADMIN1', 'AUTH_XTSZ_DEPT1', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (6, 'ROLE_PLATFORMADMIN1', 'AUTH_XTSZ_USER2', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (7, 'ROLE_SYSADMIN3', 'AUTH_XTSZ_DEPT1', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (8, 'ROLE_SYSADMIN3', 'AUTH_XTSZ_USER2', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (9, 'ROLE_USER2', 'AUTH_LOGIN4', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (10, 'ROLE_LOGINTOWELCOME4', 'AUTH_LOGIN4', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (11, 'ROLE_USER2', 'AUTH_AFTERLOGINWELCOME5', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463962718, '1303463949640', 'AUTH_LOGIN4', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463972234, 'ROLE_WORK', 'AUTH_LOGIN4', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463972235, 'ROLE_WORK', 'AUTH_AFTERLOGINWELCOME5', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463972250, 'ROLE_WORK', 'AUTH_XTSZ_DEPT1', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463972251, 'ROLE_WORK', 'AUTH_XTSZ_USER2', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303463972265, 'ROLE_WORK', 'AUTH_NODE_MGR3', 1); insert into SYS_ROLES_AUTHORITIES (ID, ROLE_ID, AUTHORITY_ID, ENABLED) values (1303287600015, 'ROLE_LOGIN', 'AUTH_LOGIN4', 1); commit; prompt 18 records loaded prompt Loading SYS_USERS![]() insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304494573750', 'lxb', 'lxb', 'c7d3f4c857bc8c145d6e5d40c1bf23d9', null, 1, 0, '10011001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304490737406', 'lxb', 'lxb', 'c7d3f4c857bc8c145d6e5d40c1bf23d9', null, 1, 0, '10011001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304574079546', 'ddd', 'ddd', '0a4f6a961276619f7f91356bcba5a746', null, 0, 0, null, null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304573363921', 'lxb', '卢小兵', '09eb37d219cfa835db40e5ab587f7082', '普通仅登录到欢迎界面!', 0, 0, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304573484515', 'lll', 'lll', '47acedc22cef8c3762c21a435e262d67', null, 1, 0, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('admin1', 'admin', '系统管理员', 'ceb4f32325eda6142bd65215f4c0f371', '超级系统管理员', 1, 1, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('user2', 'user', '普通用户', '47a733d60998c719cf3526ae7d106d13', '普通用户', 1, 0, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('sysUser3', 'sysUser', '系统设置维护', '8f0295328c34f8eedc2362e9f4a10b7e', '系统设置用户', 1, 0, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('lxb4', 'lxb', '卢小兵', 'c7d3f4c857bc8c145d6e5d40c1bf23d9', '普通仅登录到欢迎界面!', 1, 0, '1001', null, '01'); insert into SYS_USERS (USER_ID, USER_ACCOUNT, USER_NAME, USER_PASSWORD, USER_DESC, ENABLED, ISSYS, USER_DEPT, USER_DUTY, SUB_SYSTEM) values ('1304566319625', 'lxb5', 'lx5', '1abe40ed6d0da1c834586e8ecef61fe7', null, 0, 0, '10011001', null, '01'); commit; prompt 10 records loaded prompt Loading SYS_USERS_ROLES![]() insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED) values (1, 'admin1', 'ROLE_PLATFORMADMIN1', 1); insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED) values (2, 'sysUser3', 'ROLE_SYSADMIN3', 1); insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED) values (3, 'user2', 'ROLE_USER2', 1); insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED) values (4, 'lxb4', 'ROLE_LOGINTOWELCOME4', 1); insert into SYS_USERS_ROLES (ID, USER_ID, ROLE_ID, ENABLED) values (5, '1304573484515', '1303463518765', null); commit; prompt 5 records loaded prompt Enabling foreign key constraints for SYS_AUTHORITIES_RESOURCES![]() alter table SYS_AUTHORITIES_RESOURCES enable constraint FK_PUB_AUTHORITIES_RE_AU; alter table SYS_AUTHORITIES_RESOURCES enable constraint FK_PUB_AUTHORITIES_RE_RE; prompt Enabling foreign key constraints for SYS_ROLES_AUTHORITIES![]() alter table SYS_ROLES_AUTHORITIES enable constraint FK_PUB_ROLES_AUTHORITIES_AU; alter table SYS_ROLES_AUTHORITIES enable constraint FK_PUB_ROLES_AUTHORITIES_ROLES; prompt Enabling foreign key constraints for SYS_USERS_ROLES![]() alter table SYS_USERS_ROLES enable constraint FK_USERS_ROLES_ROLES; alter table SYS_USERS_ROLES enable constraint FK_USERS_ROLES_USERS; prompt Enabling triggers for SYS_AUTHORITIES![]() alter table SYS_AUTHORITIES enable all triggers; prompt Enabling triggers for SYS_RESOURCES![]() alter table SYS_RESOURCES enable all triggers; prompt Enabling triggers for SYS_AUTHORITIES_RESOURCES![]() alter table SYS_AUTHORITIES_RESOURCES enable all triggers; prompt Enabling triggers for SYS_ROLES![]() alter table SYS_ROLES enable all triggers; prompt Enabling triggers for SYS_ROLES_AUTHORITIES![]() alter table SYS_ROLES_AUTHORITIES enable all triggers; prompt Enabling triggers for SYS_USERS![]() alter table SYS_USERS enable all triggers; prompt Enabling triggers for SYS_USERS_ROLES![]() alter table SYS_USERS_ROLES enable all triggers; set feedback on set define on prompt Done.![]()
web.xml与第一种方法同。 applicationContext-security.xml:
<?xml version="1.0" encoding="UTF-8"?>![]() <b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">![]() ![]() <http auto-config="true" access-denied-page="/accessDenied.jsp"> <!-- 不要过滤图片等静态资源 --> <intercept-url pattern="/**/*.jpg" filters="none" /> <intercept-url pattern="/**/*.png" filters="none" /> <intercept-url pattern="/**/*.gif" filters="none" /> <intercept-url pattern="/**/*.css" filters="none" /> <intercept-url pattern="/**/*.js" filters="none" /> <!-- 登录页面和忘记密码页面不过滤 --> <intercept-url pattern="/login.jsp" filters="none" /> <intercept-url pattern="/jsp/forgotpassword.jsp" filters="none" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" />![]() <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) --> <remember-me data-source-ref="dataSource" /> <!-- 检测失效的sessionId,超时时定位到另外一个URL --> <session-management invalid-session-url="/sessionTimeout.jsp" /> <!-- 增加一个自定义的filter,放在FILTER_SECURITY_INTERCEPTOR之前, 实现用户、角色、权限、资源的数据库管理。 --> <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/> </http> <!-- 一个自定义的filter,必须包含authenticationManager, accessDecisionManager,securityMetadataSource三个属性。 --> <b:bean id="myFilter" class="avatar.base.security.MyFilterSecurityInterceptor"> <b:property name="authenticationManager" ref="authenticationManager"/> <b:property name="accessDecisionManager" ref="myAccessDecisionManager"/> <b:property name="securityMetadataSource" ref="mySecurityMetadataSource"/> </b:bean> ![]() <!-- 注意能够为authentication-manager 设置alias别名 --> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userDetailsManager"> <password-encoder ref="passwordEncoder"> <salt-source user-property="username" /> </password-encoder> </authentication-provider> </authentication-manager>![]() ![]() <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 --> <b:bean id="myAccessDecisionManager" class="avatar.base.security.MyAccessDecisionManager"> </b:bean> ![]() ![]() <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。 --> <b:bean id="mySecurityMetadataSource" class="avatar.base.security.MyInvocationSecurityMetadataSourceService"> </b:bean> ![]() </b:beans>
<?xml version="1.0" encoding="UTF-8"?>![]() <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">![]() <!-- 定义上下文返回的消息的国际化。 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/> </bean>![]() <!-- 事件监听:实现了 ApplicationListener监听接口, 包括AuthenticationCredentialsNotFoundEvent 事件, AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事 件。 --> <bean class="org.springframework.security.authentication.event.LoggerListener" />![]() <!-- 用户的密码加密或解密 --> <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />![]() <!-- 用户详细信息管理:数据源、用户缓存(通过数据库管理用户、角色、权限、资源)。 --> <bean id="userDetailsManager" class="avatar.base.security.MyUserDetailsService"> <property name="pubUsersHome" ref="pubUsersHome" /> <property name="pubAuthoritiesResourcesHome" ref="pubAuthoritiesResourcesHome" /> <property name="dataSource" ref="dataSource" /> <property name="userCache" ref="userCache" /> </bean> <!-- 启用用户的缓存功能 --> <bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> <property name="cache" ref="userEhCache" /> </bean> <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheName" value="userCache" /> <property name="cacheManager" ref="cacheManager" /> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />![]() ![]() <!-- spring security自带的与权限有关的数据读写Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>![]() </beans>
为了叙述的严谨性,这里说的是Spring Security3.0.2,而非其他版本,这是因为我只读过Spring Security3.0.2的代码,并且在该版本上面扩展自定义的 在扩展后的Spring Security3.0.2中,验证及授权的过程如下: 2、该MyInvocationSecurityMetadataSourceService类在执行时会提取数据库中所有的用户权限,形成权限列表; 3、当用户登录时,AuthenticationManager进行响应,通过用户输入的用户名和密码,然后再根据用户定义的密码算法和盐值等进行计算并和数据库比对, 4、当用户点击某个功能时,触发MyAccessDecisionManager类,该类通过decide方法对用户的资源访问进行拦截。 那好,我们在MyAccessDecisionManager类的decide这个方法里,将通过URL取得的权限列表进行循环,然后跟第3步中登录的用户所具有的权限进行比对,若相同,则表明该用户具有访问该资源的权利。 不大明白吧? 简单地说, 在数据库中我们定义了访问“LOGIN”这个URL必须是具有ROLE_ADMIN权限的人来访问,那么,登录用户恰恰具有该ROLE_ADMIN权限,两者的比对过程中,就能够返回TRUE,可以允许该用户进行访问。就这么简单! 不过在第2步的时候,一定要注意,MyInvocationSecurityMetadataSoruceService类的loadResourceDefine()方法中,形成以URL为key,权限列表为value的Map时,
第三种方法BTW 当然,你在设计了7张表之后,那么对于这些之间相互关联的关系内容及信息内容,就得由你来进行维护了,大约有用户、角色、权限、资源的增删改查,并还需要设置用户和角色、角色和权限、权限和资源之间的关系。可考虑分为三个菜单进行维护,用户设置、角色设置、资源设置。 在用户设置里分别管理用户、用户与角色的关系;在角色设置里管理角色、角色与权限的关系; 在资源设置里分别管理权限、权限与资源的关系等。
第四种方法就是直接修改源码以达到第三种方法的效果。 本来准备是直接从源码修改来的, 但是始终认为修改源码并非终极解决之道,有违OO的精神本质,再者由于时间关系,只是对代码进行了研究,但并没有进行实现或验证。只待以后时间稍稍宽松时再做为兴趣进行研究,在次不过多的讲解。但据我从代码上来看,一是将从配置文件中获取用户及权限的功能修改为从数据库中提取出来;二是将从配置文件中获取权限和资源的对应关系修改为从数据库中提取;三是修改User增加相关信息等。 始终还是围绕着JdbcDaoImpl和DefaultFilterInvocationSecurityMetadataSource还有User这3个类进行修改。 有兴趣的就先试试吧,等试好了告诉我一声哈。 Spring Security的优缺点 不可否认,Spring Security依赖于Spring的Ioc、AOP等机制,横切开系统的业务组件,将通用的权限功能注入到业务组件内部,实现了通用功能和业务功能的无缝整合,但又保证了通用功能和业务功能的实现上的分离,省却了一部分工作量,这是其存在的最重要意义。 但又不可否认,Spring Security所具有的缺乏动态资源管理的硬伤(若是能够提供用户、角色、权限和资源的数据库管理,并且提供管理界面那实在是太完美了,可惜这两样一样都不能实现),又令国人用户爱恨交加。 该何去何从,就请自己做个选择吧! -东营 sparta-紫杉 原创,转载请注明出处 :) http://www.blogjava.net/SpartaYew/ SpartaYew@163.com QQ:22086526 posted on 2011-05-19 18:03 sparta-紫杉 阅读(56330) 评论(203) 编辑 收藏 所属分类: SSH2 |
|



* @(#) MyFilterSecurityInterceptor.java 2011-3-23 上午07:53:03
}
浙公网安备 33010602011771号
评论
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
大神!能发我一份DEMO吗?。QQ77509028# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能给我发一份第三种方法的例子吗,我是初学者,光照着文章根本写不出来,谢谢,我的邮箱是: c8679724@163.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
我是初学spring security,看了些许相关资料,我所要实现的是楼主的第三种方法,但是错误连连,求助啊楼主,邮箱:564643499@qq.comqq:564643499 希望楼主能加我QQ
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
大神楼主,能发我一份demo给我参考下么。谢谢。邮箱:542419098@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主啊,非常感谢你!能不能给我发份demo啊? 谢谢!1370098@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
写的很不错啊!非常感谢!# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主啊,能不能给我发一份完整的jar包啊,我都找崩溃了,求助啊楼主,邮箱:ylw758@126.com 先谢谢了!# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
老板,能不能给我发一个hibernate+spring+struts2 + Spring security3.1的例子啊,谢谢啊# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
不好意思,忘记留邮箱了,jql850405@gmail.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
尊敬伟大的楼主,也给我一份吧hellofreckles@gmail.com
感激不尽啦
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主V5 楼主能传我一份吗? 724324522@qq.com 谢谢了# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
给我也发一份吧,bingfengfzl@163.com.谢谢楼主了# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
尊敬伟大的楼主,也给我一份吧yong458@126.com
感激不尽啊
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
给发一份吧,s_bobo_2002@163.com.谢谢楼主了# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
尊敬伟大的楼主,请发一份给我吧强力拜托
献上鄙人邮箱一枚···
124001623@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
看了楼主的东西受益匪浅,希望楼主发份demo, 谢谢,邮箱:912672215@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主啊,求demo啊,尤其是第二个方案啊,我十分十分的迫切啊,楼主好人啊。我的邮箱啊:56071912@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
请问,如果需要结合cas sso,应该如何调整配置?org.springframework.security.cas.web.CasAuthenticationFilter也是需要配置成custom-filter# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
您好,正在学习中,看您写的比较详细!不知能否发份完整的!syyxlhj@126.com!多谢!# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能发我一份带jar包的吗。非常感谢!13791296@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能发我一份带jar包的吗。非常感谢!1130399615@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
本人不得不专门上楼主这里一趟,感谢楼主的伟大。# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主能不能发份lib包给我呀,我正在研究这个安全框架啊。跪求!!!万分感谢!!!,616606266@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
if (urlMatcher.pathMatchesUrl(url, resURL)) ,url和resURL的位置写反了吧??# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
求源码 谢谢690651174@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
看来我来的有点晚了,不过我最着急,最近的项目spring mvc的,权限弄得头都大了LZ,能不能发到我邮箱1083261887@qq.com,非常感谢# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
156436756@qq.com可以发一份完整的源码给我吗??谢谢了 最近也在学习这个东西
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
149423669@qq.com可以发一份完整的源码给我吗??谢谢了 .JAR包太难找了
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
谢谢 a52071453@126.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
最近项目急需spring security ,找了很久就你这点写得最好,能否发一份完整代码给我看看,邮箱598820200@qq.com,万分感谢# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
特别想看看你的第四种方法,研究一下发一份给我吧。感激不尽。315920386@qq.com万分感激# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
最近项目急需spring security ,找了很久感觉你的例子应该能用,能否发一份工程jar包,邮箱317923230@qq.com。万分感谢。# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
.classpath这个文件里有jar包信息
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
很好# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
很好 www.qinqinbu.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
能给我发一个完整的实例吗?392342084@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能给我发一个完整的实例吗?smilefengyun@163.com 谢谢# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主您好,能否把你的Struts2+spring3+hibernate3+security3例子发一份给我,邮箱fristflayone@yeah.net# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主。你好!麻烦您发一下你的源码。
邮箱:479195110@qq.com
thank you
# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主,这个demo的jar包实在找不全,麻烦你能发份完整版到我邮箱,谢谢,好人一生平安QQ邮箱: 1131041776@qq.com
谢了。
# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
你的表做得可真够乱的//平台中的子系统
private String module;
private Set<SysUsersRoles> sysUsersRoles = new HashSet<SysUsersRoles>(0);
private Set<SysRolesAuthorities> sysRolesAuthorities = new HashSet<SysRolesAuthorities>(0);
角色认证,认证什么?不就是角色能有的模块吗?给个module不就行了,还给sysUsersRoles干吗?再给个sysRolesAuthorities干吗,不多余吗?不要说是spring security的逻辑.这样的问题真的乱多,该有的映射没有,不该的一堆,你是不是也想绕大家一下啊,让大家也好好学习一下是吗?
基础表:模块,角色,用户;扩展表:角色模块(url,也可以说是角色权限),用户角色
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主好强大啊,能把Struts2+spring3+hibernate3+security3例子发份给我吗?最近在学习springSecurity,谢谢!万分感谢!邮箱地址:306963591@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
很感谢楼主,分析得深入,有功底!希望能够把代码拿下来研究一下。。谢谢啊maidou7788@126.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
感谢楼主,正在学习security,请给我发一demo的源码(最好能带jar)。我的邮箱是c8679724@163.com,
谢谢
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
牛人呐,我正在学习security,能发一demo的源码(最好能带jar)给我学习吗。我的邮箱是282217489@qq.com,
伏地拜谢中。。。
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主你好,能发一份第三种的demo给我吗?我是这个框架的初学者,网上资料难找,谢谢你了!我的邮箱是defsakl123@126.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
感谢楼主的分享,能否发下完整的Demo .谢谢了。jackylt_lu@163.com
QQ:86922668
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能否发下完整的Demo ,万分感谢楼主,菜鸟学习中~~499699448@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
@xlplwjy最近也在学习这个,看了楼主的帖子精心收藏,但是想问问楼主能不能把整个工程发来,跑起来体验一下。非常感谢,邮箱 706830094@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
最近也在学习这个,看了楼主的帖子精心收藏,但是想问问楼主能不能把整个工程发来,跑起来体验一下。非常感谢,邮箱 706830094@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
可否发一份完整代码过来运行下??非常感谢10786989@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
看了一下楼主的例子,感觉说的挺全面的,希望楼主给发一份完整的demo,让我运行下,学习学习,万分感谢!120748096@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
非常好的文章,说了很多容易出错的细节希望楼主能把完整的例子发一份
278293262@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主写的非常好,能给我发个demo学习下吗,我的邮箱是147799824@qq.com,谢谢了啊。# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主能发份完整demo学习下么?邮箱511098425@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主能发份完整的代码不?邮箱53873039o@sina.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
有没有最新版本的,发我一份。我邮箱:qq280206735@163.com
# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主是好人哪,也发我一份呗。 78787398@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
膜拜lz!小弟邮箱chming198809@163.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
感谢楼主了,衷心感谢,象楼主这样既分享,而且非常的仔细,真的是学到不少东西,非常感谢了啊# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
第三种方式中,修改了或添加了资源必须要重启服务吗?有没有解决方法?# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
我觉得很有学习的价值, lz能发一份完整的例子给鄙人学习学习吗?568624640@qq.com 万分感谢!!
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
写的非常好麻烦发一个例子给我
182448356@qq.com,万分感谢
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主,你好,能把相关jar 传我一份吗 ,搞了好久一直调不出来!邮箱:526630938@qq.com
谢谢了!
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
安安# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
你好,能不能把完整的项目以及数据库发给我一份,谢谢 729612262@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
写得不错,我现在是新手,刚学,能不能发个源码给我研究一下,谢谢!zggitemail@163.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
麻烦这位大哥发一份给我,谢谢了,写得很好,应该有很多年的开发的经验了吧?我的邮箱402854377@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
果断收藏,,顶楼主# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
能不能发lib的包给我,谢谢啦邮箱:90yuetian@163.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
您好,我也正在研究权限这一块,你否给我一份源码,万分感谢。471839345@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
我也非常想要Demo,谢谢楼主,我的邮箱:237135053@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主,能也发一份demo给我不,谢谢924629736@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
可以把lib的包给我,非常感谢邮箱:xy709900456@163.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主的文章写得很精彩,能否也发我一份demo,非常感谢472579211@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
现在正在学习springsecurity。。希望楼主能给我发一份demo、非常感谢!!!zqcynthia1003@sina.cn
# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
急切需要一份demo,文章深受大益,谢谢794090871@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
公司正在做这一块,以前没接触过,能把代码发我份么# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
求代码和lib包 278668155@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
如果要定义某模块有几种操作权限,是不是要在资源表中也定义对应某模块的几种操作资源路径呢?# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主如果可以的话,发一份/Files/SpartaYew/framework.rar 的lib包给我,非常感谢!howard.hangxm@qq.com总觉得这个资源表定义很是麻烦,一个模块有N中操作权限,或者说有N种访问路径,就要都要在资源表中定义,不知道我有没有理解错,如果是这样,那我觉得维护配置太麻烦
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主,麻烦您给我发一个份整合的jar包吧,我自己整合的jar包老是冲突,SpringSurity和Struts2冲突,谢谢了# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
对了我的Email:dabing69221@163.com,忘了写,不好意思啊# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
lz精神可嘉, 但是写出来的东西一般, 还是谢谢了, 起到一个指路的作用.# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
看到第二种方法,有点困惑,没有自己写代码,怎样去load用户的权限呢。只有配置文件的话,怎样去找到数据库对应的哪张权限表!另求代码904033152@qq.com,谢谢
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主,可否给我一份spring+security的demo包含lib包,或者就截个lib包的图片给我 谢谢 1622581010@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
尊敬伟大的楼主,也给我一份吧1242550103@qq.com
感激不尽啊
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
楼主永生 QQ邮箱707208280@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
给我发一份源码吧邮箱76162111@qq.com
谢谢
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
请您给我一份源码吧,谢谢邮箱2448318433@qq.com
# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
給我发一份源码,谢谢.79772264@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
http://j2eeedu.taobao.com,可以找到完整的spring security3系列视频# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
请您给我一份源码吧,谢谢邮箱1151767736@qq.com
# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主V5,我最近在用这个,能发一份源码吗,502353141@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
330498266@qq.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
感谢楼主的分享 求代码一份 icafe152@163.com# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
真心佩服楼主 能否求得源码一份 pf1987@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
麻烦楼主发我一份源码,感谢!446077685@qq.com# re: 春天的故事-Spring Security3十五日研究[未登录] 回复 更多评论
楼主,您好,我根据您上述所述我自己搭了一个环境,但是MyAccessDecisionManager这个类只在我登陆后的请求进行拦截,登陆完之后的界面里的请求就进不去该类里面,我不知道为什么,您能根据您的经验判断大概是什么原因么,感谢!我用的是spingmvc+spring+mybaits框架# re: 春天的故事-Spring Security3十五日研究 回复 更多评论
@Servicepublic class MyInvocationSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource {
@Autowired
private PubAuthoritiesResourcesHome pubAuthoritiesResourcesHome;
pubAuthoritiesResourcesHome能注入进去吗?不是null??