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


    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
  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/mingluosunshan/p/5205901.html
Copyright © 2020-2023  润新知