Spring Security 3.0配置参考
MyEclipse中Spring Security 3.0.3无废话配置(第一章):http://andy-ghg.iteye.com/blog/1071639
MyEclipse中Spring Security 3.0.3无废话配置(第二章):http://andy-ghg.iteye.com/blog/1081622
Spring Security应用实例(一):用户登录 : http://sunjiesh.iteye.com/blog/365907
Spring Security3.1 最新配置实例: http://blog.csdn.net/k10509806/article/details/6369131
spring security 3 自定义认证,授权示例 http://chen-rojer-gmail-com.iteye.com/blog/1037973
xml被扫描顺序参考: http://sence-qi.iteye.com/blog/1328902
由于服务器启动时的加载配置文件的顺序为web.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),由于root-context.xml配置文件中Controller会先进行扫描装配,但是此时service还没有进行事务增强处理,得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力)
先按照http://panyongzheng.iteye.com/blog/1475762这里配置完SpringMVC&Hibernate,在增加spring能力时,同时选择spring security jar,并实现全注解方式。注意:service.impl里面的类,如是要是先回滚,那应该throws RuntimeException。
MyEclipse中Spring Security 3.0.3无废话配置
第一件事,下载中文说明文档,搜索一下就能找到。
第二件事,找到官方原版英文说明文档,搜索一下就能找到。
第三件事,需要注意的问题:
1.请使用MyEclipse 自带的Spring 3与Spring Security 3(以下简称SS3),我的MyEclipse是8.6,自带的版本是SS3.0.3。
2.登录的表单用户名必须是j-username,密码必须是j-password,表单的action必须是"/你的项目/j_spring_security_check",这里是否可以定制,我不清楚。
3.MyEclise 8.6自带的Hibernate与Spring与SS3之间没有任何Jar包冲突,出现问题请不要怀疑Jar包的问题。(至少我的目前为止没有任何冲突)
4.注意头文件,Spring的头文件是:
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/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-2.5.xsd"> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="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"> </beans:beans>
<!--Spring的ApplicationContext 载入 --> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- SpringSecurity filter--> <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>
<import resource="applicationContext-security.xml"/>
<http auto-config='true'> <intercept-url pattern="/**" access="ROLE_USER" /> </http>
<authentication-manager> <authentication-provider> <user-service> <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" /> <user name="bob" password="bobspassword" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager>
<http auto-config='true' access-denied-page="/common/403.jsp"> <intercept-url pattern="/css/**" filters="none" /> <intercept-url pattern="/images/**" filters="none" /> <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <form-login login-page='/login.jsp' /> <intercept-url pattern="/**" access="ROLE_USER" /> /> </http>
<authentication-manager> <authentication-provider> <user-service> <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" /> <user name="bob" password="bobspassword" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager>
package cn.com.fri.security.supports; 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 javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; 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 org.springframework.transaction.annotation.Transactional; import cn.com.fri.security.dao.interfaces.IAuthoritiesDAO; import cn.com.fri.security.dao.interfaces.IResourcesDAO; import cn.com.fri.security.vo.Authorities; import cn.com.fri.security.vo.Resources; /** * * 此类在初始化时,应该取到所有资源及其对应角色的定义 * */ @Service("securityMetadataSource") public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { @Autowired private IAuthoritiesDAO authoritiesDAO; @Autowired private IResourcesDAO resourcesDAO; private UrlMatcher urlMatcher = new AntUrlPathMatcher();; private static Map<String, Collection<ConfigAttribute>> resourceMap = null; public MyInvocationSecurityMetadataSource() { } /** * 在此处,将数据库中所有的资源以及对应的权限加入到内存中 */ @PostConstruct public void loadResourceDefine() { resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); System.out.println(authoritiesDAO); List<Authorities> auth = authoritiesDAO.findAll(); for (Authorities au : auth) { ConfigAttribute ca = new SecurityConfig(au.getAuthorname()); atts.add(ca); } List<Resources> res = resourcesDAO.findAll(); for (Resources resources : res) { resourceMap.put(resources.getResourcesstring(), atts); } System.out.println("权限加载完毕"); } // According to a URL, Find out permission configuration of this URL. @Transactional(readOnly = true) public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { // guess object is a URL. String url = ((FilterInvocation) object).getRequestUrl(); Iterator<String> ite = resourceMap.keySet().iterator(); while (ite.hasNext()) { String resURL = ite.next(); if (urlMatcher.pathMatchesUrl(url, resURL)) { return resourceMap.get(resURL); } } return null; } public boolean supports(Class<?> clazz) { return true; } public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } public void setAuthoritiesDAO(IAuthoritiesDAO authoritiesDAO) { this.authoritiesDAO = authoritiesDAO; } public void setResourcesDAO(IResourcesDAO resourcesDAO) { this.resourcesDAO = resourcesDAO; } }
package cn.com.fri.security.supports; 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; import org.springframework.stereotype.Service; @Service("myAccessDecisionManagerBean") 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(); for (GrantedAuthority ga : authentication.getAuthorities()) { if (needRole.equals(ga.getAuthority())) { // ga is user's role. return; } } } throw new AccessDeniedException("no right"); } public boolean supports(ConfigAttribute attribute) { // TODO Auto-generated method stub return true; } public boolean supports(Class<?> clazz) { return true; } }
package cn.com.fri.security.supports; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; 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 org.springframework.transaction.annotation.Transactional; import cn.com.fri.security.dao.interfaces.IUsersDAO; import cn.com.fri.security.vo.Authorities; import cn.com.fri.security.vo.CustomUser; import cn.com.fri.security.vo.Users; @Service("userDetailsService") public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private IUsersDAO dao; @Transactional(readOnly = true) public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { System.out.println(username); Users user = dao.findByUsername(username).get(0);//此查询由自己去实现 if (user == null) throw new UsernameNotFoundException("user not found"); Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); List<Authorities> auths = dao.findAutByUsername(username);//此查询由自己去实现如果用户表中已经包含了权限,就无需进行这一步操作了。 System.out.println(">>>>>>获得的权限有:" + auths.size() + "个"); for (Authorities a : auths) { GrantedAuthorityImpl authorityImpl = new GrantedAuthorityImpl(a .getAuthorname()); authorities.add(authorityImpl); } CustomUser u = new CustomUser(username, user.getPsw(), user .getEnabled(), true, true, true, authorities); u.setUser(user); return u; } }
GrantedAuthorityImpl authorityImpl = new GrantedAuthorityImpl("ROLE_ADMIN"); authorities.add(authorityImpl);
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="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="/common/403.jsp"> <!-- 以下为不需要权限就能访问的资源**意思就是包括子目录也同样适用 --> <intercept-url pattern="/css/**" filters="none" /> <intercept-url pattern="/app/**" filters="none" /> <intercept-url pattern="/images/**" filters="none" /> <intercept-url pattern="/swf/**" filters="none" /> <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <form-login login-page='/login.jsp' default-target-url="/index.do" always-use-default-target="true" /> <!-- 配置退出登录 --> <logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp" /> <session-management invalid-session-url="/error.html"> <concurrency-control max-sessions="1" expired-url="/error.html" /> </session-management> <!-- 配置登录验证,包括权限的启动都在这里: --> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter" /> </http> <!-- 配置登录验证的类 --> <beans:bean id="daoAuthenticationProvider" ref="userDetailsService" /> </beans:bean> <beans:bean id="authenticationManager" /> </beans:list> </beans:property> </beans:bean> <authentication-manager> <authentication-provider user-service-ref="userDetailsService"> </authentication-provider> </authentication-manager> <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性, 我们的所有控制将在这三个类中实现,这里使用了annocation,所以ref后面的参数在XML配置中是没有的,详细看这三个类。 --> <beans:bean id="myFilter" ref="authenticationManager" /> <beans:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" /> <beans:property name="securityMetadataSource" ref="securityMetadataSource" /> </beans:bean> </beans:beans>