Spring Security-利用URL地址進行權限控制


目的是:系統內存在很多不同的用戶,每個用戶具有不同的資源訪問權限,具體表現就是某個用戶對於某個URL是無權限訪問的。需要Spring Security忙我們過濾。

本文的很多命名都是參考鏈接博文的,最大的不同應該是本文是基於Spring boot,再次也向前人致敬!

由上一篇可知,FilterSecurityInterceptor是Spring Security進行URL權限判斷的, FilterSecurityInterceptor又繼承於AbstractSecurityInterceptor,由此可推測,我們可以新增一個Interceptor繼承 AbstractSecurityInterceptor,實現我們自己的權限校驗邏輯。

查看父類及其代碼邏輯,有幾點必須要注意:
1、主要鑒權方法是調用父類中accessDecisionManager的decide值,所以我們需要自己實現一個 accessDecisionManager
2、父類中存在抽象方法public abstract SecurityMetadataSource obtainSecurityMetadataSource();作用是獲取URL及用戶角色對應的關系。我們需要加入自己的實現。

以下是部分代碼實現
主要攔截器JwtUrlSecurityInterceptor,需要在WebSecurityConfig(Spring Security配置)文件中注冊
   
   
   
           
  1. //這個攔截器用來實現按照用戶權限,對所請求的url進行攔截
  2. @Bean
  3. public JwtUrlSecurityInterceptor jwtUrlSecurityInterceptorBean() throws Exception{
  4. return new JwtUrlSecurityInterceptor();
  5. }
  6. @Override
  7. protected void configure(HttpSecurity httpSecurity) throws Exception {
  8. ...
  9. httpSecurity.addFilterBefore(jwtUrlSecurityInterceptorBean(), FilterSecurityInterceptor.class);
  10. ...
  11. }
實現自定義的 accessDecisionManager
    
    
    
            
  1. package org.zerhusen.security.dsuri;
  2. import org.springframework.security.access.AccessDecisionManager;
  3. import org.springframework.security.access.AccessDeniedException;
  4. import org.springframework.security.access.ConfigAttribute;
  5. import org.springframework.security.authentication.InsufficientAuthenticationException;
  6. import org.springframework.security.core.Authentication;
  7. import java.util.Collection;
  8. /**
  9. * Created by dingshuo on 2017/6/28.
  10. */
  11. public class MyAccessDecisionManager implements AccessDecisionManager {
  12. @Override
  13. public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
  14. System.out.println("自定義的接口");
  15. throw new AccessDeniedException("no right");
  16. }
  17. @Override
  18. public boolean supports(ConfigAttribute attribute) {
  19. return true;
  20. }
  21. @Override
  22. public boolean supports(Class<?> clazz) {
  23. return true;
  24. }
  25. }
實現自定義的資源 SecurityMetadataSource  
    
    
    
            
  1. package org.zerhusen.security.dsuri;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.security.access.ConfigAttribute;
  4. import org.springframework.security.access.SecurityConfig;
  5. import org.springframework.security.web.FilterInvocation;
  6. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
  7. import java.util.*;
  8. /**
  9. * Created by dingshuo on 2017/6/28.
  10. */
  11. public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
  12. private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
  13. @Autowired
  14. UrlMatcher urlMatcher;
  15. public MyInvocationSecurityMetadataSource() {
  16. //這里可以查數據庫實現
  17. //注入dao即可
  18. resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
  19. Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
  20. ConfigAttribute ca = new SecurityConfig("ROLE_USER1");
  21. atts.add(ca);
  22. resourceMap.put("/index.jsp", atts);
  23. Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>();
  24. ConfigAttribute cano = new SecurityConfig("ROLE_NO");
  25. attsno.add(cano);
  26. resourceMap.put("/other.jsp", attsno);
  27. }
  28. @Override
  29. public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
  30. String url = ((FilterInvocation)object).getRequestUrl();
  31. Iterator<String> ite = resourceMap.keySet().iterator();
  32. while (ite.hasNext()) {
  33. String resURL = ite.next();
  34. if (url.equals("/protected")) {
  35. return resourceMap.get(resURL);
  36. }
  37. }
  38. return null;
  39. }
  40. @Override
  41. public Collection<ConfigAttribute> getAllConfigAttributes() {
  42. return null;
  43. }
  44. @Override
  45. public boolean supports(Class<?> clazz) {
  46. return true;
  47. }
  48. }
實現 JwtUrlSecurityInterceptor
      
      
      
              
  1. package org.zerhusen.security.dsuri;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.security.access.AccessDecisionManager;
  5. import org.springframework.security.access.SecurityMetadataSource;
  6. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
  7. import org.springframework.security.access.intercept.InterceptorStatusToken;
  8. import org.springframework.security.authentication.AuthenticationManager;
  9. import org.springframework.security.web.FilterInvocation;
  10. import javax.servlet.*;
  11. import java.io.IOException;
  12. /**
  13. * Created by dingshuo on 2017/6/28.
  14. */
  15. public class JwtUrlSecurityInterceptor extends AbstractSecurityInterceptor implements
  16. Filter {
  17. @Autowired
  18. public void setMyAccessDecisionManager(){
  19. super.setAccessDecisionManager(myAccessDecisionManagerBean());
  20. }
  21. @Bean
  22. public MyAccessDecisionManager myAccessDecisionManagerBean(){
  23. return new MyAccessDecisionManager();
  24. }
  25. @Bean
  26. public MyInvocationSecurityMetadataSource myInvocationSecurityMetadataSourceBean(){
  27. return new MyInvocationSecurityMetadataSource();
  28. }
  29. @Override
  30. public void init(FilterConfig filterConfig) throws ServletException {
  31. }
  32. @Override
  33. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  34. FilterInvocation fi = new FilterInvocation(request, response, chain);
  35. invoke(fi);
  36. }
  37. @Override
  38. public void destroy() {
  39. }
  40. @Override
  41. public Class<?> getSecureObjectClass() {
  42. return FilterInvocation.class;
  43. }
  44. @Override
  45. public SecurityMetadataSource obtainSecurityMetadataSource() {
  46. return this.myInvocationSecurityMetadataSourceBean();
  47. }
  48. public void invoke(FilterInvocation fi) throws IOException, ServletException {
  49. InterceptorStatusToken token = super.beforeInvocation(fi);
  50. try {
  51. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
  52. }finally {
  53. super.afterInvocation(token, null);
  54. }
  55. }
  56. }
如上是簡單的URL權限控制


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM