参考文档: http://wenku.baidu.com/view/4ec7e324ccbff121dd368364.html
在spring security3中使用自己定义的数据结构来实现权限设置。
- 数据库
- 用户表
- 角色表
- action表,即资源表
- 角色-用户关联表
- actiion-角色关联表
- 配置过程
- web.xml中加入过滤器
-
- <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>
-
- 在applicationContext.xml中import spring security部分的配置
- <import resource="security3.0_JPA.xml"/>
- 配置import resource="security3.0_JPA.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns="http://www./schema/security" xmlns:beans="http://www./schema/beans" xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:schemaLocation="http://www./schema/beans
- http:
- http:
- http:
- <http auto-config="true" access-denied-page="/jsp/accessDenied.jsp">
- <intercept-url pattern="/css/**" filters="none" />
- <intercept-url pattern="/images/**" filters="none" />
- <intercept-url pattern="/js/**" filters="none" />
- <!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,
- 这个filter位于FILTER_SECURITY_INTERCEPTOR之前 -->
- <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR" />
- </http>
- <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性,
- 我们的所有控制将在这三个类中实现,解释详见具体配置 -->
- <beans:bean id="myFilter" class="com.softvan.spring.security.FilterSecurityInterceptor">
- <beans:property name="authenticationManager" ref="MyAuthenticationManager" />
- <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
- <beans:property name="accessDecisionManager" ref="AccessDecisionManager" />
- <beans:property name="securityMetadataSource" ref="MySecurityMetadataSource" />
- </beans:bean>
- <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 -->
- <beans:bean id="MySecurityMetadataSource" init-method="loadResourceDefine" class="com.softvan.spring.security.InvocationSecurityMetadataSourceService">
- <beans:property name="roleService" ref="RoleService" />
- <beans:property name="actionService" ref="ActionService" />
- </beans:bean>
-
- <!-- 验证配置 , 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
- <authentication-manager alias="MyAuthenticationManager">
- <authentication-provider user-service-ref="UserDetailService">
- <!--
- <s:password-encoder hash="sha" />
- -->
- </authentication-provider>
- </authentication-manager>
- </beans:beans>
- 相关java代码
- AccessDecisionManager.java
-
-
-
- package com.softvan.spring.security;
- import org.apache.log4j.Logger;
-
-
-
-
-
- import java.util.Collection;
- import java.util.Iterator;
- 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("AccessDecisionManager")
- public class AccessDecisionManager implements org.springframework.security.access.AccessDecisionManager {
-
-
-
- private static final Logger logger = Logger.getLogger(AccessDecisionManager.class);
-
-
-
-
-
-
-
- public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
- if (logger.isDebugEnabled()) {
- logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - start");
- }
- if (configAttributes == null) {
- if (logger.isDebugEnabled()) {
- logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
- }
- return;
- }
- if (logger.isDebugEnabled()){
- logger.debug("正在访问的url是:"+object.toString());
- }
- Iterator<ConfigAttribute> ite = configAttributes.iterator();
- while (ite.hasNext()) {
- ConfigAttribute ca = ite.next();
- logger.debug("needRole is:"+ca.getAttribute());
- String needRole = ((SecurityConfig) ca).getAttribute();
- for (GrantedAuthority ga : authentication.getAuthorities()) {
- logger.debug("/t授权信息是:"+ga.getAuthority());
- if (needRole.equals(ga.getAuthority())) {
- if (logger.isDebugEnabled()) {
- logger.debug("判断到,needRole 是"+needRole+",用户的角色是:"+ga.getAuthority()+",授权数据相匹配");
- logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
- }
- return;
- }
- }
- }
- throw new AccessDeniedException("没有权限");
- }
- public boolean supports(ConfigAttribute attribute) {
-
- return true;
- }
- public boolean supports(Class<?> clazz) {
- return true;
- }
- }
- FilterSecurityInterceptor.java
-
-
-
- package com.softvan.spring.security;
- import org.apache.log4j.Logger;
-
-
-
-
-
- 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;
- public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
-
-
-
- private static final Logger logger = Logger.getLogger(FilterSecurityInterceptor.class);
- private FilterInvocationSecurityMetadataSource securityMetadataSource;
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- if (logger.isDebugEnabled()) {
- logger.debug("doFilter(ServletRequest, ServletResponse, FilterChain) - start");
- }
- FilterInvocation fi = new FilterInvocation(request, response, chain);
- invoke(fi);
- if (logger.isDebugEnabled()) {
- logger.debug("doFilter(ServletRequest, ServletResponse, FilterChain) - end");
- }
- }
- 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 {
-
- }
- }
- InvocationSecurityMetadataSourceService.java
- UserDetailService.java
-
-
-
- package com.softvan.spring.security;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Set;
- import javax.inject.Inject;
- import org.apache.log4j.Logger;
- import org.springframework.dao.DataAccessException;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.authority.GrantedAuthorityImpl;
- import org.springframework.security.core.userdetails.User;
- 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 com.alcor.acl.domain.TRole;
- import com.alcor.acl.domain.TUser;
- @Service("UserDetailService")
- public class UserDetailService implements UserDetailsService {
-
-
-
- private static final Logger logger = Logger.getLogger(UserDetailService.class);
- @Inject
- com.alcor.acl.component.User user ;
-
- public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException, DataAccessException {
- if (logger.isDebugEnabled()) {
- logger.debug("loadUserByUsername(String) - start");
- }
-
- Collection<GrantedAuthority> auths=new ArrayList<GrantedAuthority>();
-
- String password=null;
-
- TUser tUser = user.getUserByName(username);
- if (tUser ==null){
- String message = "用户"+username+"不存在";
- logger.error(message);
- throw new UsernameNotFoundException(message);
- }
- password=user.getUserByName(username).getPassword();
-
-
- Set<TRole> tRoles =tUser.getTRoles();
- for(TRole item : tRoles){
- GrantedAuthorityImpl grantedAuthorityImpl = new GrantedAuthorityImpl(item.getRoleName());
- if (logger.isDebugEnabled()){
- logger.debug("用户:["+tUser.getName()+"]拥有角色:["+item.getRoleName()+"],即spring security中的access");
- }
- auths.add(grantedAuthorityImpl);
- }
-
- User user = new User(username,password, true, true, true, true, auths);
-
- if (logger.isDebugEnabled()) {
- logger.debug("loadUserByUsername(String) - end");
- }
- return user;
- }
- }