码迷,mamicode.com
首页 > 编程语言 > 详细

SpringSecurity 自定义用户 角色 资源权限控制

时间:2016-02-22 00:22:23      阅读:652      评论:0      收藏:0      [点我收藏+]

标签:

SpringSecurity 自定义用户 角色 资源权限控制

 

技术分享
  1 package com.joyen.learning.security;
  2 
  3 import java.sql.ResultSet;
  4 import java.sql.SQLException;
  5 import java.util.List;
  6 
  7 import org.springframework.context.support.MessageSourceAccessor;
  8 import org.springframework.dao.DataAccessException;
  9 import org.springframework.jdbc.core.RowMapper;
 10 import org.springframework.jdbc.core.support.JdbcDaoSupport;
 11 import org.springframework.security.core.GrantedAuthority;
 12 import org.springframework.security.core.SpringSecurityMessageSource;
 13 import org.springframework.security.core.authority.AuthorityUtils;
 14 import org.springframework.security.core.authority.GrantedAuthorityImpl;
 15 import org.springframework.security.core.userdetails.UserDetails;
 16 import org.springframework.security.core.userdetails.UserDetailsService;
 17 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 18 
 19 /**
 20  * 在这个类中,从数据库中读入用户的密码,角色信息,是否锁定,账号是否过期等
 21  * @author fwj
 22  *
 23  */
 24 public class MyUserDetailService extends JdbcDaoSupport implements UserDetailsService {
 25 
 26     
 27     private String authoritiesByUsernameQuery;
 28     private String usersByUsernameQuery;
 29     
 30     protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
 31     
 32     public UserDetails loadUserByUsername(String username)
 33             throws UsernameNotFoundException, DataAccessException {
 34         List<MyUser> users = loadUsersByUsername(username);
 35         
 36         if (users==null || users.size() == 0) {
 37             logger.debug("Query returned no results for user ‘" + username + "‘");
 38 
 39             throw new UsernameNotFoundException(
 40                     messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);
 41         }
 42         
 43         MyUser user = users.get(0);
 44         List<GrantedAuthority> dbAuths = loadUserAuthorities(user.getUsername());
 45         
 46         if (dbAuths == null || dbAuths.size() == 0) {
 47             logger.debug("User ‘" + username + "‘ has no authorities and will be treated as ‘not found‘");
 48 
 49             throw new UsernameNotFoundException(
 50                     messages.getMessage("JdbcDaoImpl.noAuthority",
 51                             new Object[] {username}, "User {0} has no GrantedAuthority"), username);
 52         }
 53         
 54         return createUserDetails(username,user,dbAuths);
 55         
 56     }
 57     
 58     protected List<MyUser> loadUsersByUsername(String username) {
 59         
 60         return getJdbcTemplate().query(usersByUsernameQuery, new String[] {username}, new RowMapper<MyUser>() {
 61             public MyUser mapRow(ResultSet rs, int rowNum) throws SQLException {
 62                 String username = rs.getString(1);
 63                 String password = rs.getString(2);
 64                 String email = rs.getString(3);
 65                 boolean enabled = rs.getBoolean(4);
 66                 return new MyUser(username, password, email, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
 67             }
 68 
 69         });
 70     }
 71     
 72     protected List<GrantedAuthority> loadUserAuthorities(String username) {
 73         return getJdbcTemplate().query(authoritiesByUsernameQuery, new String[] {username}, new RowMapper<GrantedAuthority>() {
 74             public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
 75                 String roleName = rs.getString(2);
 76                 GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
 77 
 78                 return authority;
 79             }
 80         });
 81     }
 82     
 83     protected UserDetails createUserDetails(String username, MyUser userFromUserQuery,
 84             List<GrantedAuthority> combinedAuthorities) {
 85         String returnUsername = userFromUserQuery.getUsername();
 86 
 87         return new MyUser(returnUsername, userFromUserQuery.getPassword(), userFromUserQuery.getEmail(), userFromUserQuery.isEnabled(),
 88                 true, true, true, combinedAuthorities);
 89     }
 90 
 91     public String getAuthoritiesByUsernameQuery() {
 92         return authoritiesByUsernameQuery;
 93     }
 94 
 95     public void setAuthoritiesByUsernameQuery(String authoritiesByUsernameQuery) {
 96         this.authoritiesByUsernameQuery = authoritiesByUsernameQuery;
 97     }
 98 
 99     public String getUsersByUsernameQuery() {
100         return usersByUsernameQuery;
101     }
102 
103     public void setUsersByUsernameQuery(String usersByUsernameQuery) {
104         this.usersByUsernameQuery = usersByUsernameQuery;
105     }
106     
107     
108 
109 }
MyUserDetailService

 

技术分享
 1 package com.joyen.learning.security;
 2 
 3 import java.util.Collection;
 4 
 5 import org.springframework.security.core.GrantedAuthority;
 6 import org.springframework.security.core.userdetails.User;
 7 
 8 public class MyUser extends User {
 9 
10     /**
11      * 
12      */
13     private static final long serialVersionUID = 1L;
14     private final String email;
15     
16     public MyUser(String username, String password, String email, boolean enabled,
17             boolean accountNonExpired, boolean credentialsNonExpired,
18             boolean accountNonLocked,
19             Collection<? extends GrantedAuthority> authorities) {
20         
21         super(username, password, enabled, accountNonExpired, credentialsNonExpired,
22                 accountNonLocked, authorities);
23         // TODO Auto-generated constructor stub
24         this.email = email;
25     }
26 
27     public String getEmail() {
28         return email;
29     }
30     
31 }
MyUser

 

技术分享
 1 package com.joyen.learning.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 MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
19 
20 
21     private FilterInvocationSecurityMetadataSource securityMetadataSource;  
22     
23     public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
24         return securityMetadataSource;
25     }
26 
27     public void setSecurityMetadataSource(
28             FilterInvocationSecurityMetadataSource securityMetadataSource) {
29         this.securityMetadataSource = securityMetadataSource;
30     }
31 
32     @Override
33     public Class<? extends Object> getSecureObjectClass() {
34         return FilterInvocation.class;
35     }
36 
37     @Override
38     public SecurityMetadataSource obtainSecurityMetadataSource() {
39         return this.securityMetadataSource;
40     }
41 
42     public void destroy() {
43         // TODO Auto-generated method stub
44         
45     }
46 
47     public void doFilter(ServletRequest request, ServletResponse response,
48             FilterChain chain) throws IOException, ServletException {
49         FilterInvocation fi = new FilterInvocation(request, response, chain);  
50         invoke(fi);
51         
52     }
53 
54     public void init(FilterConfig arg0) throws ServletException {
55         // TODO Auto-generated method stub
56         
57     }
58     
59     public void invoke(FilterInvocation fi) throws IOException, ServletException {
60         InterceptorStatusToken token = super.beforeInvocation(fi);
61         try {
62             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
63         } finally {
64            super.afterInvocation(token, null);
65         }
66     }
67 
68 }
MyFilterSecurityInterceptor

 

技术分享
 1 package com.joyen.learning.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.access.SecurityConfig;
10 import org.springframework.security.authentication.InsufficientAuthenticationException;
11 import org.springframework.security.core.Authentication;
12 import org.springframework.security.core.GrantedAuthority;
13 import org.springframework.security.web.FilterInvocation;
14 
15 /**
16  * 决策类
17  * 如果不存在对该资源的定义,直接放行;否则,如果找到正确的角色,即认为拥有权限,并放行
18  * @author fwj
19  *
20  */
21 public class MyAccessDecisionManager implements AccessDecisionManager {
22 
23     public void decide(Authentication authentication, Object object,
24             Collection<ConfigAttribute> configAttributes)
25             throws AccessDeniedException, InsufficientAuthenticationException {
26         
27         if(configAttributes == null){
28             return ;
29          }
30          
31          FilterInvocation fi = (FilterInvocation)object;
32          System.out.println("=============request url==========="+fi.getRequestUrl());  //object is a URL.
33          Iterator<ConfigAttribute> ite=configAttributes.iterator();  
34         while(ite.hasNext()){
35              ConfigAttribute ca=ite.next();
36              String needRole=((SecurityConfig)ca).getAttribute();
37             for(GrantedAuthority ga:authentication.getAuthorities()){
38                 if(needRole.equals(ga.getAuthority())){  //ga is user‘s role.  
39                     return;  
40                  }  
41              }  
42          }  
43         throw new AccessDeniedException("no right");  
44 
45     }
46 
47     public boolean supports(ConfigAttribute attribute) {
48         // TODO Auto-generated method stub
49         return true;
50     }
51 
52     public boolean supports(Class<?> clazz) {
53         // TODO Auto-generated method stub
54         return true;
55     }
56 
57 }
MyAccessDecisionManager

 

技术分享
 1 package com.joyen.learning.security;
 2 
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.util.ArrayList;
 6 import java.util.Collection;
 7 import java.util.HashMap;
 8 import java.util.Iterator;
 9 import java.util.List;
10 import java.util.Map;
11 
12 import javax.sql.DataSource;
13 
14 import org.springframework.jdbc.core.RowMapper;
15 import org.springframework.jdbc.core.support.JdbcDaoSupport;
16 import org.springframework.security.access.ConfigAttribute;
17 import org.springframework.security.access.SecurityConfig;
18 import org.springframework.security.web.FilterInvocation;
19 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
20 import org.springframework.security.web.util.AntUrlPathMatcher;
21 import org.springframework.security.web.util.UrlMatcher;
22 
23 /** 
24 *  
25 * 此类在初始化时,应该取到所有资源及其对应角色的定义 
26 *  
27 * @author fuwenjun 
28 *  
29 */  
30 public class MyInvocationSecurityMetadataSource extends JdbcDaoSupport implements
31         FilterInvocationSecurityMetadataSource {
32     
33     private String resourceQuery;
34     private UrlMatcher urlMatcher = new AntUrlPathMatcher();
35     private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
36 
37     public MyInvocationSecurityMetadataSource(DataSource dataSource,String resourceQuery) {
38         this.setDataSource(dataSource);
39         this.resourceQuery = resourceQuery;
40         this.loadResourceDefine();
41     }
42 
43     private void loadResourceDefine(){
44         resourceMap = new HashMap<String, Collection<ConfigAttribute>>();  
45         List<ResourceRole> list = getJdbcTemplate().query(resourceQuery, new RowMapper<ResourceRole>() {
46                                         public ResourceRole mapRow(ResultSet rs, int rowNum) throws SQLException {
47                                             String url = rs.getString(1);
48                                             String role = rs.getString(2);
49                                             return new ResourceRole(url, role);
50                                         }
51                                     });
52         ConfigAttribute ca = null;
53         Collection<ConfigAttribute> cca = null;
54         for (ResourceRole resourceRole : list) {
55             if(resourceMap.containsKey(resourceRole.getUrl())){
56                 ca = new SecurityConfig(resourceRole.getRole());
57                 resourceMap.get(resourceRole.getUrl()).add(ca);
58             }else{
59                 ca = new SecurityConfig(resourceRole.getRole());
60                 cca = new ArrayList<ConfigAttribute>();//首次创建一个新的configattribute集合
61                 cca.add(ca);
62                 resourceMap.put(resourceRole.getUrl(), cca);
63             }
64         }
65         
66     }
67     
68     public Collection<ConfigAttribute> getAttributes(Object object)
69             throws IllegalArgumentException {
70        String url = ((FilterInvocation)object).getRequestUrl();  
71        Iterator<String> ite = resourceMap.keySet().iterator();  
72        while (ite.hasNext()) {
73             String resURL = ite.next();  
74            if (urlMatcher.pathMatchesUrl(url, resURL)) {
75                return resourceMap.get(resURL);  
76             }
77         }
78        return null;
79     }
80 
81     public Collection<ConfigAttribute> getAllConfigAttributes() {
82         // TODO Auto-generated method stub
83         return null;
84     }
85 
86     public boolean supports(Class<?> clazz) {
87         // TODO Auto-generated method stub
88         return true;
89     }
90     
91 }
MyInvocationSecurityMetadataSource

 

技术分享
 1 package com.joyen.learning.security;
 2 
 3 public class ResourceRole {
 4 
 5     private String url;
 6     private String role;
 7 
 8     public ResourceRole(String url, String role) {
 9         this.url = url;
10         this.role = role;
11     }
12 
13     public String getUrl() {
14         return url;
15     }
16 
17     public String getRole() {
18         return role;
19     }
20 }
ResourceRole

 

技术分享
 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"  
 4      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 5      xsi:schemaLocation="http://www.springframework.org/schema/beans  
 6             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
 7             http://www.springframework.org/schema/security  
 8             http://www.springframework.org/schema/security/spring-security-3.0.xsd">
 9             
10     <http access-denied-page="/403" auto-config="false"><!-- 当访问被拒绝时,会转到403.jsp -->  
11         <intercept-url pattern="/login" filters="none" />  
12         <form-login login-page="/login"  
13              authentication-failure-url="/login?error=true"  
14              default-target-url="/index"/>
15         <logout logout-success-url="/login" />
16         <!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,这个filter位于FILTER_SECURITY_INTERCEPTOR之前 -->  
17         <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter" />  
18     </http>  
19     
20     <!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->  
21     <authentication-manager alias="authenticationManager">  
22         <authentication-provider  
23             user-service-ref="myUserDetailService">  
24             <!--    如果用户的密码采用加密的话,可以加点“盐”  
25                  <password-encoder hash="md5" />  
26             -->  
27         </authentication-provider>  
28     </authentication-manager>  
29     
30     
31     <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性,我们的所有控制将在这三个类中实现,解释详见具体配置 -->  
32     <beans:bean id="myFilter" class="com.joyen.learning.security.MyFilterSecurityInterceptor">  
33         <beans:property name="authenticationManager"  
34              ref="authenticationManager" />  
35         <beans:property name="accessDecisionManager"  
36              ref="myAccessDecisionManagerBean" />  
37         <beans:property name="securityMetadataSource"  
38              ref="securityMetadataSource" />  
39     </beans:bean>
40     
41     
42     <beans:bean id="myUserDetailService"
43          class="com.joyen.learning.security.MyUserDetailService">
44          <beans:property name="dataSource" ref="dataSource"></beans:property>
45         <beans:property name="usersByUsernameQuery" value="select username,password,email,enabled from user where username = ?"></beans:property>
46         <beans:property name="authoritiesByUsernameQuery" value="SELECT u.username,r.name
47                                                                     FROM user u,roleuser ru, role r
48                                                                     WHERE u.id = ru.userid
49                                                                     AND ru.roleid = r.id
50                                                                     AND u.username = ?"></beans:property>
51     </beans:bean>
52   
53     <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->  
54     <beans:bean id="myAccessDecisionManagerBean"  
55          class="com.joyen.learning.security.MyAccessDecisionManager">  
56     </beans:bean>  
57       
58     <!-- 资源源数据定义,即定义某一资源可以被哪些角色访问 -->  
59     <beans:bean id="securityMetadataSource"
60          class="com.joyen.learning.security.MyInvocationSecurityMetadataSource">
61         <beans:constructor-arg ref="dataSource"></beans:constructor-arg>
62         <beans:constructor-arg type="java.lang.String" value="select rce.url, r.name from role r inner join roleresource rrce on r.id = rrce.roleid inner join resource rce on rrce.resourceid = rce.id"></beans:constructor-arg>
63     </beans:bean>
64 </beans:beans>
spring-security.xml

 

SpringSecurity 自定义用户 角色 资源权限控制

标签:

原文地址:http://www.cnblogs.com/mingluosunshan/p/5205901.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!