登录流程

1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)

 2)用户发出请求

 3)过滤器拦截(MySecurityFilter:doFilter)

 4)取得请求资源所需权限(MySecurityMetadataSource:getAttributes)

 5)匹配用户拥有权限和请求权限(MyAccessDecisionManager:decide),如果用户没有相应的权限,


     执行第6步,否则执行第7步。

 6)登录

 7)验证并授权(MyUserDetailServiceImpl:loadUserByUsername)


1、web.xml中加入过滤器



  1. <!-- SpringSecurity 核心过滤器配置 -->  
  2. <filter>  
  3.     <filter-name>springSecurityFilterChain</filter-name>  
  4.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  5. </filter>  
  6. <filter-mapping>  
  7.     <filter-name>springSecurityFilterChain</filter-name>  
  8.     <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  
<!-- SpringSecurity 核心过滤器配置 -->
<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>



2、新建spring-security.xml文件


  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans:beans xmlns="http://www.springframework.org/schema/security"  
  3.     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.     http://www.springframework.org/schema/security  
  7.     http://www.springframework.org/schema/security/spring-security.xsd">  
  8.   
  9.     <!-- entry-point-ref 配置自定义登录 -->  
  10.     <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">  
  11.           
  12.         <!-- 登出配置 -->  
  13.         <logout logout-url="/j_spring_security_logout" logout-success-url="/login" />  
  14.   
  15.         <access-denied-handler error-page="/noPower" />  
  16.           
  17.         <!-- 过滤不被拦截的请求 -->  
  18.         <intercept-url pattern="/login*" access="permitAll" />  
  19.         <intercept-url pattern="/resources/**" access="permitAll" />  
  20.           
  21.         <!-- 只有权限才能访问的请求 -->  
  22.         <intercept-url pattern="/admin/**" access="isAuthenticated()" />  
  23.   
  24.         <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />  
  25.         <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />  
  26.   
  27.     </http>  
  28.   
  29.     <beans:bean id="loginFilter"  
  30.         class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter">  
  31.           
  32.         <!-- 登录提交处理 -->  
  33.         <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>  
  34.           
  35.         <!-- 登录成功跳转 -->  
  36.         <beans:property name="authenticationSuccessHandler"  
  37.             ref="loginLogAuthenticationSuccessHandler"></beans:property>  
  38.           
  39.         <!-- 设置登录失败的网址 -->  
  40.         <beans:property name="authenticationFailureHandler"  
  41.             ref="simpleUrlAuthenticationFailureHandler"></beans:property>  
  42.           
  43.         <!-- 用户拥有权限 -->     
  44.         <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>  
  45.     </beans:bean>  
  46.   
  47.     <beans:bean id="loginLogAuthenticationSuccessHandler"  
  48.         class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">  
  49.         <beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>  
  50.     </beans:bean>  
  51.     <beans:bean id="simpleUrlAuthenticationFailureHandler"  
  52.         class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
  53.         <beans:property name="defaultFailureUrl" value="/login"></beans:property>  
  54.     </beans:bean>  
  55.   
  56.     <authentication-manager alias="myAuthenticationManager">  
  57.         <authentication-provider user-service-ref="myUserDetailServiceImpl">  
  58.             <password-encoder ref="encoder" />  
  59.         </authentication-provider>  
  60.     </authentication-manager>  
  61.   
  62.     <beans:bean id="myUserDetailServiceImpl"  
  63.         class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">  
  64.     </beans:bean>  
  65.   
  66.     <beans:bean id="authenticationProcessingFilterEntryPoint"  
  67.         class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
  68.         <beans:property name="loginFormUrl" value="/login"></beans:property>  
  69.     </beans:bean>  
  70.   
  71.     <!-- 认证过滤器 -->  
  72.     <beans:bean id="securityFilter"  
  73.         class="cn.com.abel.test.service.security.MySecurityFilter">  
  74.         <!-- 用户拥有的角色 -->  
  75.         <beans:property name="authenticationManager" ref="myAuthenticationManager" />  
  76.         <!-- 用户是否拥有所请求资源的权限 -->  
  77.         <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />  
  78.         <!-- 资源与角色的对应关系 -->  
  79.         <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />  
  80.         <!-- <beans:property name="rejectPublicInvocations" value="true"/> -->  
  81.   
  82.     </beans:bean>  
  83.       
  84.     <beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean>  
  85.       
  86.     <beans:bean id="mySecurityMetadataSource"  
  87.         class="cn.com.abel.test.service.security.MySecurityMetadataSource">  
  88.         <beans:constructor-arg>  
  89.             <beans:ref bean="resourceService" />  
  90.         </beans:constructor-arg>  
  91.     </beans:bean>  
  92.   
  93.     <beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>  
  94.     
  95. </beans: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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- entry-point-ref 配置自定义登录 -->
<http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">

<!-- 登出配置 -->
<logout logout-url="/j_spring_security_logout" logout-success-url="/login" />

<access-denied-handler error-page="/noPower" />

<!-- 过滤不被拦截的请求 -->
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />

<!-- 只有权限才能访问的请求 -->
<intercept-url pattern="/admin/**" access="isAuthenticated()" />

<custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
<custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />

</http>

<beans:bean id="loginFilter"
class="cn.com.abel.test.service.security.MyUsernamePasswordAuthenticationFilter">

<!-- 登录提交处理 -->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>

<!-- 登录成功跳转 -->
<beans:property name="authenticationSuccessHandler"
ref="loginLogAuthenticationSuccessHandler"></beans:property>

<!-- 设置登录失败的网址 -->
<beans:property name="authenticationFailureHandler"
ref="simpleUrlAuthenticationFailureHandler"></beans:property>

<!-- 用户拥有权限 -->
<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean>

<beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/admin/index"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login"></beans:property>
</beans:bean>

<authentication-manager alias="myAuthenticationManager">
<authentication-provider user-service-ref="myUserDetailServiceImpl">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>

<beans:bean id="myUserDetailServiceImpl"
class="cn.com.abel.test.service.security.AdminUserDetailServiceImpl">
</beans:bean>

<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login"></beans:property>
</beans:bean>

<!-- 认证过滤器 -->
<beans:bean id="securityFilter"
class="cn.com.abel.test.service.security.MySecurityFilter">
<!-- 用户拥有的角色 -->
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<!-- 用户是否拥有所请求资源的权限 -->
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<!-- 资源与角色的对应关系 -->
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
<!-- <beans:property name="rejectPublicInvocations" value="true"/> -->

</beans:bean>

<beans:bean id="myAccessDecisionManager" class="myAccessDecisionManager"></beans:bean>

<beans:bean id="mySecurityMetadataSource"
class="cn.com.abel.test.service.security.MySecurityMetadataSource">
<beans:constructor-arg>
<beans:ref bean="resourceService" />
</beans:constructor-arg>
</beans:bean>

<beans:bean id="encoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>

</beans:beans>




3、MyUsernamePasswordAuthenticationFilter.java


  1. package cn.com.abel.test.service.security;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.springframework.security.authentication.AuthenticationServiceException;  
  7. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
  8. import org.springframework.security.core.Authentication;  
  9. import org.springframework.security.core.AuthenticationException;  
  10. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
  11.   
  12. public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{  
  13.   
  14.     @Override  
  15.     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {  
  16.   
  17.         if (!request.getMethod().equals("POST")) {  
  18.             throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());  
  19.         }  
  20.   
  21.         String username = obtainUsername(request);  
  22.         String password = obtainPassword(request);  
  23.   
  24.         if (username == null) {  
  25.             username = "";  
  26.         }  
  27.   
  28.         if (password == null) {  
  29.             password = "";  
  30.         }  
  31.   
  32.         username = username.trim();  
  33.   
  34.         UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);  
  35.   
  36.         // Allow subclasses to set the "details" property  
  37.         setDetails(request, authRequest);  
  38.   
  39. //      //登录验证码,如需要开启把下面注释去掉则可  
  40. //      String authCode = StringUtils.defaultString(request.getParameter("authCode"));  
  41. //      if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){  
  42. //          throw new AuthenticationServiceException("validCode.auth.fail");  
  43. //      }  
  44.   
  45.         return this.getAuthenticationManager().authenticate(authRequest);  
  46.     }  
  47. }  
package cn.com.abel.test.service.security;
import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationServiceException;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.AuthenticationException;

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}

String username = obtainUsername(request);
String password = obtainPassword(request);

if (username == null) {
username = "";
}

if (password == null) {
password = "";
}

username = username.trim();

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

// Allow subclasses to set the "details" property
setDetails(request, authRequest);

// //登录验证码,如需要开启把下面注释去掉则可

// String authCode = StringUtils.defaultString(request.getParameter("authCode"));

// if(!AdwImageCaptchaServlet.validateResponse(request, authCode)){

// throw new AuthenticationServiceException("validCode.auth.fail");

// }

return this.getAuthenticationManager().authenticate(authRequest);
}

}



4、MySecurityFilter.java


  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11.   
  12. import org.springframework.security.access.SecurityMetadataSource;  
  13. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;  
  14. import org.springframework.security.access.intercept.InterceptorStatusToken;  
  15. import org.springframework.security.web.FilterInvocation;  
  16. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  17.   
  18. public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {  
  19.     //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,  
  20.     //其他的两个组件,已经在AbstractSecurityInterceptor定义  
  21.     private FilterInvocationSecurityMetadataSource securityMetadataSource;  
  22.   
  23.     @Override  
  24.     public SecurityMetadataSource obtainSecurityMetadataSource() {  
  25.         return this.securityMetadataSource;  
  26.     }  
  27.   
  28.     public void doFilter(ServletRequest request, ServletResponse response,  
  29.             FilterChain chain) throws IOException, ServletException {  
  30.         FilterInvocation fi = new FilterInvocation(request, response, chain);  
  31.         invoke(fi);  
  32.     }  
  33.       
  34.     private void invoke(FilterInvocation fi) throws IOException, ServletException {  
  35.         // object为FilterInvocation对象  
  36.         //1.获取请求资源的权限  
  37.         //执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);  
  38.         //2.是否拥有权限  
  39.         //获取安全主体,可以强制转换为UserDetails的实例  
  40.         //1) UserDetails  
  41.         // Authentication authenticated = authenticateIfRequired();  
  42.         //this.accessDecisionManager.decide(authenticated, object, attributes);  
  43.         //用户拥有的权限  
  44.         //2) GrantedAuthority  
  45.         //Collection<GrantedAuthority> authenticated.getAuthorities()  
  46.         //System.out.println("用户发送请求! ");  
  47.         InterceptorStatusToken token = null;  
  48.           
  49.         token = super.beforeInvocation(fi);  
  50.           
  51.         try {  
  52.             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());  
  53.         } finally {  
  54.             super.afterInvocation(token, null);  
  55.         }  
  56.     }  
  57.   
  58.     public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {  
  59.         return securityMetadataSource;  
  60.     }  
  61.   
  62.     public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {  
  63.         this.securityMetadataSource = securityMetadataSource;  
  64.     }  
  65.       
  66.     public void init(FilterConfig arg0) throws ServletException {  
  67.         // TODO Auto-generated method stub  
  68.     }  
  69.       
  70.     public void destroy() {  
  71.         // TODO Auto-generated method stub  
  72.           
  73.     }  
  74.   
  75.     @Override  
  76.     public Class<? extends Object> getSecureObjectClass() {  
  77.         //下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误  
  78.         return FilterInvocation.class;  
  79.     }  
  80. }  
package cn.com.abel.test.service.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;
public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {
//与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,

//其他的两个组件,已经在AbstractSecurityInterceptor定义

private FilterInvocationSecurityMetadataSource securityMetadataSource;

@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}

private void invoke(FilterInvocation fi) throws IOException, ServletException {
// object为FilterInvocation对象
//1.获取请求资源的权限
//执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object);
//2.是否拥有权限
//获取安全主体,可以强制转换为UserDetails的实例
//1) UserDetails
// Authentication authenticated = authenticateIfRequired();
//this.accessDecisionManager.decide(authenticated, object, attributes);
//用户拥有的权限
//2) GrantedAuthority
//Collection<GrantedAuthority> authenticated.getAuthorities()
//System.out.println("用户发送请求! ");
InterceptorStatusToken token = null;

token = super.beforeInvocation(fi);

try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}

public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return securityMetadataSource;
}

public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
}

public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}

public void destroy() {
// TODO Auto-generated method stub

}

@Override
public Class<? extends Object> getSecureObjectClass() {
//下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
return FilterInvocation.class;
}

}



5、AdminUserDetailServiceImpl.java


  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.List;  
  5. import java.util.Set;  
  6.   
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.security.core.GrantedAuthority;  
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  10. import org.springframework.security.core.userdetails.UserDetails;  
  11. import org.springframework.security.core.userdetails.UserDetailsService;  
  12. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  13.   
  14. import cn.com.abel.test.model.RoleModel;  
  15. import cn.com.abel.test.model.MemberModel;  
  16. import cn.com.abel.test.service.RoleService;  
  17. import cn.com.abel.test.service.MemberService;  
  18.   
  19. public class AdminUserDetailServiceImpl implements UserDetailsService {  
  20.     @Autowired  
  21.     private MemberService memberService;  
  22.     @Autowired  
  23.     RoleService roleService;  
  24.    
  25.     //登录验证  
  26.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
  27.           
  28.        
  29.         MemberModel member = memberService.getUserDetailsByUserName(username);  
  30.           
  31.         if(member==null){  
  32.             throw new UsernameNotFoundException("member "+username +" not found.");  
  33.         }  
  34.         Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member);  
  35.   
  36.                 //封装成spring security的user  
  37.                 User userdetail = new User(user.getUserName(), user.getPassword(),  
  38.                 true, // 账号状态 0 表示停用 1表示启用  
  39.                 true, true, true, grantedAuths // 用户的权限  
  40.                 );  
  41.                 return userdetail;  
  42.     }  
  43.       
  44.     //取得用户的权限  
  45.     private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) {  
  46.           
  47.         Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();  
  48.           
  49.         List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>  
  50.         if(roles!=null){  
  51.             for(RoleModel role : roles) {  
  52.                 authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));  
  53.             }  
  54.         }  
  55.    
  56.         return authSet;  
  57.     }  
  58.       
  59. }  
package cn.com.abel.test.service.security;
import java.util.HashSet;

import java.util.List;

import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.core.GrantedAuthority;

import org.springframework.security.core.authority.SimpleGrantedAuthority;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.core.userdetails.UsernameNotFoundException;
import cn.com.abel.test.model.RoleModel;

import cn.com.abel.test.model.MemberModel;

import cn.com.abel.test.service.RoleService;

import cn.com.abel.test.service.MemberService;
public class AdminUserDetailServiceImpl implements UserDetailsService {

@Autowired

private MemberService memberService;

@Autowired

RoleService roleService;

//登录验证
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {


MemberModel member = memberService.getUserDetailsByUserName(username);

if(member==null){
throw new UsernameNotFoundException("member "+username +" not found.");
}
Set<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(member);

//封装成spring security的user
User userdetail = new User(user.getUserName(), user.getPassword(),
true, // 账号状态 0 表示停用 1表示启用
true, true, true, grantedAuths // 用户的权限
);
return userdetail;
}

//取得用户的权限
private Set<GrantedAuthority> obtionGrantedAuthorities(MemberModel member) {

Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();

List<RoleModel> roles = roleService.getRoleByUser(member)<span style="font-family:Arial, Helvetica, sans-serif;">;</span>
if(roles!=null){
for(RoleModel role : roles) {
authSet.add(new SimpleGrantedAuthority(role.getRoleCode().trim()));
}
}

return authSet;
}

}



6、MyAccessDecisionManager.java


  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.Collection;  
  4. import java.util.Iterator;  
  5.   
  6. import org.springframework.security.access.AccessDecisionManager;  
  7. import org.springframework.security.access.AccessDeniedException;  
  8. import org.springframework.security.access.ConfigAttribute;  
  9. import org.springframework.security.authentication.InsufficientAuthenticationException;  
  10. import org.springframework.security.core.Authentication;  
  11. import org.springframework.security.core.GrantedAuthority;  
  12.   
  13. public class MyAccessDecisionManager implements AccessDecisionManager {  
  14.       
  15.     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {  
  16.         if(configAttributes == null) {  
  17.             return;  
  18.         }  
  19.         //所请求的资源拥有的权限(一个资源对多个权限)  
  20.         Iterator<ConfigAttribute> iterator = configAttributes.iterator();  
  21.         while(iterator.hasNext()) {  
  22.             ConfigAttribute configAttribute = iterator.next();  
  23.             //访问所请求资源所需要的权限  
  24.             String needPermission = configAttribute.getAttribute();  
  25.             System.out.println("needPermission is " + needPermission);  
  26.             //用户所拥有的权限authentication  
  27.             for(GrantedAuthority ga : authentication.getAuthorities()) {  
  28.                 if(needPermission.equals(ga.getAuthority())) {  
  29.                     return;  
  30.                 }  
  31.             }  
  32.         }  
  33.         //没有权限让我们去捕捉  
  34.         throw new AccessDeniedException(" 没有权限访问!");  
  35.     }  
  36.   
  37.     public boolean supports(ConfigAttribute attribute) {  
  38.         // TODO Auto-generated method stub  
  39.         return true;  
  40.     }  
  41.   
  42.     public boolean supports(Class<?> clazz) {  
  43.         // TODO Auto-generated method stub  
  44.         return true;  
  45.     }  
  46.       
  47. }  
package cn.com.abel.test.service.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.authentication.InsufficientAuthenticationException;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.GrantedAuthority;
public class MyAccessDecisionManager implements AccessDecisionManager {

public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(configAttributes == null) {
return;
}
//所请求的资源拥有的权限(一个资源对多个权限)
Iterator<ConfigAttribute> iterator = configAttributes.iterator();
while(iterator.hasNext()) {
ConfigAttribute configAttribute = iterator.next();
//访问所请求资源所需要的权限
String needPermission = configAttribute.getAttribute();
System.out.println("needPermission is " + needPermission);
//用户所拥有的权限authentication
for(GrantedAuthority ga : authentication.getAuthorities()) {
if(needPermission.equals(ga.getAuthority())) {
return;
}
}
}
//没有权限让我们去捕捉
throw new AccessDeniedException(" 没有权限访问!");
}

public boolean supports(ConfigAttribute attribute) {
// TODO Auto-generated method stub
return true;
}

public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return true;
}

}



7、MySecurityMetadataSource.java

  1. package cn.com.abel.test.service.security;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashSet;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import java.util.Map.Entry;  
  10. import java.util.TreeMap;  
  11. import java.util.concurrent.ConcurrentHashMap;  
  12.   
  13. import javax.servlet.http.HttpServletRequest;  
  14.   
  15. import org.apache.commons.lang.StringUtils;  
  16. import org.springframework.beans.factory.InitializingBean;  
  17. import org.springframework.security.access.ConfigAttribute;  
  18. import org.springframework.security.access.SecurityConfig;  
  19. import org.springframework.security.web.FilterInvocation;  
  20. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  21. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;  
  22. import org.springframework.security.web.util.matcher.RequestMatcher;  
  23.   
  24. import cn.com.abel.test.model.RoleModel;  
  25. import cn.com.abel.test.service.ResourceService;  
  26.   
  27. public class MySecurityMetadataSource  implements FilterInvocationSecurityMetadataSource,InitializingBean {  
  28.   
  29.       
  30.     private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__";  
  31.       
  32.     private ResourceService resourceService;  
  33.       
  34.     public MySecurityMetadataSource(ResourceService resourceService) {  
  35.         this.resourceService = resourceService;  
  36.     }  
  37.   
  38.     private static Map<String, Collection<ConfigAttribute>> resourceMap = null;  
  39.   
  40.     public Collection<ConfigAttribute> getAllConfigAttributes() {  
  41.         return null;  
  42.     }  
  43.   
  44.     public boolean supports(Class<?> clazz) {  
  45.         return true;  
  46.     }  
  47.     private void loadResourceDefine() {  
  48.         if(resourceMap == null) {  
  49.             resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();  
  50.         }else{  
  51.             resourceMap.clear();  
  52.         }  
  53.           
  54.         Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole();  
  55.           
  56.         for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {  
  57.             String url = entry.getKey();  
  58.             List<RoleModel> values = entry.getValue();  
  59.               
  60.             Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();  
  61.             for(RoleModel secRoleModel : values){  
  62.                 ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));  
  63.                 configAttributes.add(configAttribute);  
  64.             }  
  65.             resourceMap.put(url, configAttributes);  
  66.         }  
  67.     }  
  68.     public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {  
  69.           
  70.         HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();    
  71.    
  72.         TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap);  
  73.           
  74.         Iterator<String> ite = attrMap.keySet().iterator();    
  75.           
  76.         RequestMatcher urlMatcher = null;    
  77.   
  78.         Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();  
  79.         //match all of /admin/**  a/b/**  
  80.         while (ite.hasNext()) {    
  81.               
  82.             String resURL = ite.next();    
  83.             urlMatcher = new AntPathRequestMatcher(resURL);  
  84.   
  85.             if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {    
  86.                 attrSet.addAll(attrMap.get(resURL));    
  87.             }    
  88.         }    
  89.   
  90.         if(!attrSet.isEmpty()){  
  91.             return attrSet;  
  92.         }  
  93.         return null;  
  94.     }  
  95.    
  96.     @Override  
  97.     public void afterPropertiesSet() throws Exception {  
  98.         loadResourceDefine() ;  
  99.     }  
  100.       
  101. }  
package cn.com.abel.test.service.security;
import java.util.ArrayList;

import java.util.Collection;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.TreeMap;

import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;

import org.springframework.beans.factory.InitializingBean;

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.matcher.AntPathRequestMatcher;

import org.springframework.security.web.util.matcher.RequestMatcher;
import cn.com.abel.test.model.RoleModel;

import cn.com.abel.test.service.ResourceService;
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource,InitializingBean {

private static final String AUTH_NO_ROLE =" __AUTH_NO_ROLE__";

private ResourceService resourceService;

public MySecurityMetadataSource(ResourceService resourceService) {
this.resourceService = resourceService;
}

private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}

public boolean supports(Class<?> clazz) {
return true;
}
private void loadResourceDefine() {
if(resourceMap == null) {
resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();
}else{
resourceMap.clear();
}

Map<String,List<RoleModel>> resourceRoleMap = resourceService.getAllResourceRole();

for (Entry<String,List<RoleModel>> entry : resourceRoleMap.entrySet()) {
String url = entry.getKey();
List<RoleModel> values = entry.getValue();

Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
for(RoleModel secRoleModel : values){
ConfigAttribute configAttribute = new SecurityConfig(StringUtils.defaultString(secRoleModel.getRoleCode(),AUTH_NO_ROLE));
configAttributes.add(configAttribute);
}
resourceMap.put(url, configAttributes);
}
}
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

TreeMap<String, Collection<ConfigAttribute>> attrMap = new TreeMap<String, Collection<ConfigAttribute>>(resourceMap);

Iterator<String> ite = attrMap.keySet().iterator();

RequestMatcher urlMatcher = null;

Collection<ConfigAttribute> attrSet = new HashSet<ConfigAttribute>();
//match all of /admin/** a/b/**
while (ite.hasNext()) {

String resURL = ite.next();
urlMatcher = new AntPathRequestMatcher(resURL);

if (urlMatcher.matches(request)||StringUtils.equals(request.getRequestURI(),resURL)) {
attrSet.addAll(attrMap.get(resURL));
}
}

if(!attrSet.isEmpty()){
return attrSet;
}
return null;
}

@Override
public void afterPropertiesSet() throws Exception {
loadResourceDefine() ;
}

}



8、ResourceService.java

此类是为从数据库获取系统中的资源所属的角色,根据自己的数据表自行编写。



  1. package cn.com.abel.test.service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. import org.apache.commons.collections.CollectionUtils;  
  10. import org.springframework.beans.factory.annotation.Autowired;  
  11. import org.springframework.stereotype.Service;  
  12.   
  13. import cn.com.abel.test.mapper.ResourceModelMapper;  
  14. import cn.com.abel.test.mapper.RoleModelMapper;  
  15. import cn.com.abel.test.mapper.RoleResourcetModelMapper;  
  16. import cn.com.abel.test.model.ResourceModel;  
  17. import cn.com.abel.test.model.ResourceModelCriteria;  
  18. import cn.com.abel.test.model.RoleModel;  
  19. import cn.com.abel.test.model.RoleModelCriteria;  
  20. import cn.com.abel.test.model.RoleResourcetModel;  
  21. import cn.com.abel.test.model.RoleResourcetModelCriteria;  
  22.   
  23. @Service  
  24. public class ResourceService {  
  25.       
  26.     @Autowired  
  27.     ResourceModelMapper resourceModelMapper;  
  28.       
  29.     @Autowired  
  30.     RoleModelMapper roleMapper;  
  31.       
  32.     @Autowired  
  33.     RoleResourcetModelMapper  roleResMapper;  
  34.       
  35.     /** 
  36.      * 获取各个资源(url)对应的角色 
  37.      * @return 
  38.      */  
  39.     public Map<String,List<RoleModel>> getAllResourceRole(){  
  40.           
  41.          Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>();  
  42.            
  43.         ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();  
  44.         List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample);  
  45.           
  46.         if(CollectionUtils.isNotEmpty(resourceList)){  
  47.             for(ResourceModel secResourceModel : resourceList){  
  48.                 RoleModelCriteria roleCriteria = new RoleModelCriteria();  
  49.                 roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));  
  50.                 List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);  
  51.                 resultMap.put(secResourceModel.getValue(), roleList);  
  52.                   
  53.             }  
  54.         }  
  55.        
  56.         return resultMap;  
  57.     }  
  58.       
  59.     public List<Integer> getRoleIdsByResourceId(Integer resourceId){  
  60.         List<Integer> roleIds = new ArrayList<Integer>();  
  61.           
  62.         RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();  
  63.         criteria.createCriteria().andResourceIdEqualTo(resourceId);  
  64.         List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);  
  65.         if(CollectionUtils.isNotEmpty(list)){  
  66.             for(RoleResourcetModel model : list){  
  67.                 roleIds.add(model.getRoleId());  
  68.             }  
  69.         }  
  70.           
  71.         HashSet<Integer> h  =   new  HashSet<Integer>(roleIds);       
  72.         roleIds.clear();       
  73.         roleIds.addAll(h);     
  74.         return roleIds;  
  75.     }  
  76. }  
package cn.com.abel.test.service;
import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;
import org.apache.commons.collections.CollectionUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import cn.com.abel.test.mapper.ResourceModelMapper;

import cn.com.abel.test.mapper.RoleModelMapper;

import cn.com.abel.test.mapper.RoleResourcetModelMapper;

import cn.com.abel.test.model.ResourceModel;

import cn.com.abel.test.model.ResourceModelCriteria;

import cn.com.abel.test.model.RoleModel;

import cn.com.abel.test.model.RoleModelCriteria;

import cn.com.abel.test.model.RoleResourcetModel;

import cn.com.abel.test.model.RoleResourcetModelCriteria;
@Service

public class ResourceService {

@Autowired
ResourceModelMapper resourceModelMapper;

@Autowired
RoleModelMapper roleMapper;

@Autowired
RoleResourcetModelMapper roleResMapper;

/**
* 获取各个资源(url)对应的角色
* @return
*/
public Map<String,List<RoleModel>> getAllResourceRole(){

Map<String,List<RoleModel>> resultMap = new HashMap<String,List<RoleModel>>();

ResourceModelCriteria secResourceModelExample = new ResourceModelCriteria();
List<ResourceModel> resourceList = resourceModelMapper.selectByExample(secResourceModelExample);

if(CollectionUtils.isNotEmpty(resourceList)){
for(ResourceModel secResourceModel : resourceList){
RoleModelCriteria roleCriteria = new RoleModelCriteria();
roleCriteria.createCriteria().andIdIn(getRoleIdsByResourceId(secResourceModel.getId()));
List<RoleModel> roleList = roleMapper.selectByExample(roleCriteria);
resultMap.put(secResourceModel.getValue(), roleList);

}
}

return resultMap;
}

public List<Integer> getRoleIdsByResourceId(Integer resourceId){
List<Integer> roleIds = new ArrayList<Integer>();

RoleResourcetModelCriteria criteria = new RoleResourcetModelCriteria();
criteria.createCriteria().andResourceIdEqualTo(resourceId);
List<RoleResourcetModel> list = roleResMapper.selectByExample(criteria);
if(CollectionUtils.isNotEmpty(list)){
for(RoleResourcetModel model : list){
roleIds.add(model.getRoleId());
}
}

HashSet<Integer> h = new HashSet<Integer>(roleIds);
roleIds.clear();
roleIds.addAll(h);
return roleIds;
}

}




  1. CREATE TABLE `auth_resource` (  
  2.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `name` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',  
  4.     `value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',  
  5.     `summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',  
  6.     `updated_time` DATETIME NULL DEFAULT NULL,  
  7.     `updated_user` VARCHAR(100) NULL DEFAULT NULL,  
  8.     PRIMARY KEY (`id`)  
  9. )  
  10. COMMENT='资源访问表'  
  11. COLLATE='utf8_general_ci'  
  12. ENGINE=InnoDB;  
  13.   
  14. CREATE TABLE `auth_role` (  
  15.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  16.     `role_name` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',  
  17.     `role_code` VARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',  
  18.     `updated_time` DATETIME NULL DEFAULT NULL,  
  19.     `updated_user` VARCHAR(100) NULL DEFAULT NULL,  
  20.     PRIMARY KEY (`id`)  
  21. )  
  22. COMMENT='角色表'  
  23. COLLATE='utf8_general_ci'  
  24. ENGINE=InnoDB;  
  25.   
  26. CREATE TABLE `role_resource` (  
  27.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  28.     `role_id` INT(11) NOT NULL,  
  29.     `resource_id` INT(11) NOT NULL,  
  30.     PRIMARY KEY (`id`),  
  31.     UNIQUE INDEX `role_id_resource_id` (`role_id`, `resource_id`)  
  32. )  
  33. COMMENT='资源角色关联表'  
  34. COLLATE='utf8_general_ci'  
  35. ENGINE=InnoDB;  
  36.   
  37. CREATE TABLE `member` (  
  38.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  39.     `user_name` VARCHAR(100) NULL DEFAULT NULL,  
  40.     `nick` VARCHAR(100) NULL DEFAULT NULL,  
  41.     `password` VARCHAR(100) NULL DEFAULT NULL,  
  42.     `sex` INT(11) NULL DEFAULT NULL,  
  43.     `birthday` DATE NULL DEFAULT NULL,  
  44.     `mobile` VARCHAR(50) NULL DEFAULT NULL,  
  45.     `email` VARCHAR(50) NULL DEFAULT NULL,  
  46.     `address` VARCHAR(512) NULL DEFAULT NULL,  
  47.     `regip` VARCHAR(100) NULL DEFAULT NULL,  
  48.     `created_time` DATETIME NULL DEFAULT NULL,  
  49.     PRIMARY KEY (`id`)  
  50. )  
  51. COMMENT='用户表'  
  52. COLLATE='utf8_general_ci'  
  53. ENGINE=InnoDB  
  54. AUTO_INCREMENT=2;  
  55.   
  56. CREATE TABLE `member_role` (  
  57.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  58.     `member_id` INT(11) NOT NULL,  
  59.     `role_id` INT(11) NOT NULL,  
  60.     PRIMARY KEY (`id`),  
  61.     UNIQUE INDEX `member_id_role_id` (`member_id`, `role_id`)  
  62. )  
  63. COMMENT='用户角色关联表'  
  64. COLLATE='utf8_general_ci'  
  65. ENGINE=InnoDB;  
CREATE TABLE `auth_resource` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源名称',
`value` VARCHAR(100) NULL DEFAULT NULL COMMENT '资源值',
`summary` VARCHAR(1000) NULL DEFAULT NULL COMMENT '资源描述',
`updated_time` DATETIME NULL DEFAULT NULL,
`updated_user` VARCHAR(100) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COMMENT='资源访问表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
CREATE TABLE auth_role (
id INT(11) NOT NULL AUTO_INCREMENT,
role_name VARCHAR(100) NULL DEFAULT NULL COMMENT '角色名称',
role_code VARCHAR(100) NULL DEFAULT NULL COMMENT '角色代码',
updated_time DATETIME NULL DEFAULT NULL,
updated_user VARCHAR(100) NULL DEFAULT NULL,

PRIMARY KEY (id)

)

COMMENT='角色表'

COLLATE='utf8_general_ci'

ENGINE=InnoDB;
CREATE TABLE role_resource (
id INT(11) NOT NULL AUTO_INCREMENT,
role_id INT(11) NOT NULL,
resource_id INT(11) NOT NULL,

PRIMARY KEY (id),

UNIQUE INDEX role_id_resource_id (role_id, resource_id)

)

COMMENT='资源角色关联表'

COLLATE='utf8_general_ci'

ENGINE=InnoDB;
CREATE TABLE member (
id INT(11) NOT NULL AUTO_INCREMENT,
user_name VARCHAR(100) NULL DEFAULT NULL,
nick VARCHAR(100) NULL DEFAULT NULL,
password VARCHAR(100) NULL DEFAULT NULL,
sex INT(11) NULL DEFAULT NULL,
birthday DATE NULL DEFAULT NULL,
mobile VARCHAR(50) NULL DEFAULT NULL,
email VARCHAR(50) NULL DEFAULT NULL,
address VARCHAR(512) NULL DEFAULT NULL,
regip VARCHAR(100) NULL DEFAULT NULL,
created_time DATETIME NULL DEFAULT NULL,

PRIMARY KEY (id)

)

COMMENT='用户表'

COLLATE='utf8_general_ci'

ENGINE=InnoDB

AUTO_INCREMENT=2;
CREATE TABLE member_role (
id INT(11) NOT NULL AUTO_INCREMENT,
member_id INT(11) NOT NULL,
role_id INT(11) NOT NULL,

PRIMARY KEY (id),

UNIQUE INDEX member_id_role_id (member_id, role_id)

)

COMMENT='用户角色关联表'

COLLATE='utf8_general_ci'

ENGINE=InnoDB;