馃憞馃憞鐩存帴杩涘叆~銆?/span>鐑ч绁堢璁告効浣犵殑鎰挎湜鎴戞潵"/>

251.Spring Boot+Spring Security锛氬熀浜嶶RL鍔ㄦ€佹潈闄愶細鑷畾涔塅ilter

Posted SpringBoot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了251.Spring Boot+Spring Security锛氬熀浜嶶RL鍔ㄦ€佹潈闄愶細鑷畾涔塅ilter相关的知识,希望对你有一定的参考价值。


鏈€杩戜竴鏈嬪弸鍋氫簡涓€涓皬绋嬪簭锛岀湅鐫€杩樻尯濂界帺鐨勶紝浜庢槸涔庡氨甯湅鍙嬫崕甯︽帹骞夸簡涓嬶紝璧拌繃璺繃鐨勫皬浼欎即浠紝浣犲績涓槸鍚︿篃鏄湁涓€涓効鏈涳紝璧剁揣鏉ヨ繖閲屽拰澶у涓€璧峰垎浜拰瀹炵幇鍚 鏉ワ紝鏉ワ紝鏉ワ紝鎴戝湪杩欓噷绛変綘~ 

銆愮偣鍑火煈?span class="mq-6">馃憞馃憞鐩存帴杩涘叆~銆?/span>

鐑ч绁堢璁告効浣犵殑鎰挎湜鎴戞潵瀹炵幇 绁堢璁告効 姊︽兂鎴愮湡  


璇存槑

锛?锛塉DK鐗堟湰锛?.8

锛?锛塖pring Boot 2.0.6

锛?锛塖pring Security 5.0.9

锛?锛塖pring Data JPA 2.0.11.RELEASE

锛?锛塰ibernate5.2.17.Final

锛?锛塎ySQLDriver 5.1.47

锛?锛塎ySQL 8.0.12


闇€姹傜紭璧?/span>

       鍦ㄤ笂涓€绡囨垜浠€氳繃鑷畾涔堿ccessDesionManager瀹炵幇浜嗗姩鎬佹潈闄愭帶鍒讹紝鏈妭灏嗛€氳繃鑷畾涔塅ilter杩涜瀹炵幇鍔ㄦ€佹潈闄愶紝鐞嗚В浜嗕笂涓€绡囨枃绔犵殑璇濓紝瀵逛簬杩欑瘒鏂囩珷灏辨病鏈変粈涔堥毦鐐逛簡銆備唬鐮佸熀浜庛€婂熀浜嶶RL鍔ㄦ€佹潈闄愶細鍑嗗宸ヤ綔銆嬪湪寰€涓嬬紪鐮併€?/span>

缂栫爜鎬濊矾

       瀵逛簬URL鍔ㄦ€佹潈闄愰厤缃紝涓昏瑙e喅濡備笅鍑犱釜闂锛?/span>

锛?锛夊熀浜嶶RL鐨勭敤鎴锋潈闄愪俊鎭繚瀛樺湪鍝噷锛氶渶瑕佸畾涔変竴寮犳潈闄愯〃锛屼繚瀛樻潈闄愪俊鎭紝鐒跺悗瑙掕壊鍜屾潈闄愭湁涓€涓叧鑱斿叧绯伙紙鍑嗗宸ヤ綔宸茬粡瀹屾垚锛夈€?/span>

锛?锛夋€庝箞鍔犺浇鐢ㄦ埛鐨勬潈闄愪俊鎭細浠嶇劧鏄€氳繃loadUserByUsername杩涜鍔犺浇锛岀敤鎴风殑鏉冮檺淇℃伅杩欏潡鐨勭紪鐮佷笉鍙橈紙鍦ㄤ箣鍓嶅凡缁忕紪鐮侊級銆?/span>

锛?锛塙RL瀵瑰簲鐨勬潈闄愰厤缃細杩欎釜涓昏鏄€氳繃FilterInvocationSecurityMetadataSource杩涜閰嶇疆銆?/span>

锛?锛夊浣曞喅瀹氭煇涓€涓敤鎴锋槸鍚︽湁鏉冮檺璁块棶鏌愪釜URL 锛?鑷畾涔堿ccessDecisionManager绫荤殑decide鏂规硶锛屽喅瀹氭煇涓€涓敤鎴锋槸鍚︽湁鏉冮檺璁块棶鏌愪釜URL銆?/span>

锛?锛変娇鐢ㄨ嚜瀹氫箟鐨凢ilter杩涜鎷︽埅澶勭悊璇锋眰銆?/span>

 

涓€銆佸熀浜嶶RL鍔ㄦ€佹潈闄愰厤缃?/span>

       鎺ヤ笅鏉ユ垜浠湅涓嬪叿浣撶殑缂栫爜姝ラ锛屾垜浠殑浠g爜鍦ㄥ熀鏈伐浣滀箣鍚庤繘琛岀紪鐮侊紝鎵€浠ユ潈闄愮殑瀹炰綋绫伙紝鍒濆鍖栨暟鎹氨涓嶉噸澶嶈鏄庝簡銆?/span>

1.1 鍔犺浇鏉冮檺淇℃伅

       缁ф壙FilterInvocationSecurityMetadataSource閲嶅啓getAttributes鐨勬柟娉曡繘琛岄€氳繃uri鑾峰彇鏉冮檺閰嶇疆淇℃伅锛?/span>

package com.kfit.config;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Component;

import com.kfit.permission.service.PermissionService;

@Component
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource{

    @Autowired
    private PermissionService permissionService;





    /**
     * 姝ゆ柟娉曟槸涓轰簡鍒ゅ畾鐢ㄦ埛璇锋眰鐨剈rl 鏄惁鍦ㄦ潈闄愯〃涓紝濡傛灉鍦ㄦ潈闄愯〃涓紝鍒欒繑鍥炵粰 decide 鏂规硶銆?br>     * object-->FilterInvocation
     */

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        System.out.println("MyFilterInvocationSecurityMetadataSource.getAttributes()");

        Map<String, Collection<ConfigAttribute>> map = permissionService.getPermissionMap();
        FilterInvocation filterInvocation = (FilterInvocation) object;
        System.out.println(filterInvocation.getFullRequestUrl());

        if (isMatcherAllowedRequest(filterInvocation)) return null ; //return null 琛ㄧず鍏佽璁块棶锛屼笉鍋氭嫤鎴?/span>

        HttpServletRequest request = filterInvocation.getHttpRequest();
        String resUrl;
        //URL瑙勫垯鍖归厤.
        AntPathRequestMatcher matcher;
        for(Iterator<String> it  = map.keySet().iterator();it.hasNext();) {
            resUrl = it.next();
            matcher = new AntPathRequestMatcher(resUrl);
            if(matcher.matches(request)) {
                System.out.println(map.get(resUrl));
                return map.get(resUrl);
            }
        }
        //SecurityConfig.createList("ROLE_USER");
         //鏂瑰紡涓€锛氭病鏈夊尮閰嶅埌,鐩存帴鏄櫧鍚嶅崟浜?涓嶇櫥褰曚篃鏄彲浠ヨ闂殑銆?/span>
        //return null;

        //鏂瑰紡浜岋細閰嶆湁鍖归厤鍒帮紝闇€瑕佹寚瀹氱浉搴旂殑瑙掕壊锛?/span>
        return SecurityConfig.createList("ROLE_admin");
    }




    /**
     * 鍒ゆ柇褰撳墠璇锋眰鏄惁鍦ㄥ厑璁歌姹傜殑鑼冨洿鍐?br>     * @param fi 褰撳墠璇锋眰
     * @return 鏄惁鍦ㄨ寖鍥翠腑
     */

    private boolean isMatcherAllowedRequest(FilterInvocation fi){
        return allowedRequest().stream().map(AntPathRequestMatcher::new)
                .filter(requestMatcher -> requestMatcher.matches(fi.getHttpRequest()))
                .toArray().length > 0;
    }

    /**
     * 鍙傝€冿細
     * https://blog.csdn.net/pujiaolin/article/details/73928491
     * @return 瀹氫箟鍏佽璇锋眰鐨勫垪琛?br>     */

    private List<String> allowedRequest(){
        return Arrays.asList("/login","/css/**","/fonts/**","/js/**","/scss/**","/img/**");
    }

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

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

}


1.2 鏉冮檺鏍¢獙

       缁ф壙AccessDecisionManager閲嶅啓decide鏂规硶杩涜缂栫爜锛?/span>

package com.kfit.config;

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;
import org.springframework.stereotype.Component;

@Component
public class MyAccessDecisionManager implements AccessDecisionManager{

    /**
     * 鏂规硶鏄垽瀹氭槸鍚︽嫢鏈夋潈闄愮殑鍐崇瓥鏂规硶锛?br>     * (1)authentication 鏄噴CustomUserService涓惊鐜坊鍔犲埌 GrantedAuthority 瀵硅薄涓殑鏉冮檺淇℃伅闆嗗悎.
     * (2)object 鍖呭惈瀹㈡埛绔彂璧风殑璇锋眰鐨剅equset淇℃伅锛屽彲杞崲涓?nbsp;HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
     * (3)configAttributes 涓篗yFilterInvocationSecurityMetadataSource鐨刧etAttributes(Object object)杩欎釜鏂规硶杩斿洖鐨勭粨鏋滐紝姝ゆ柟娉曟槸涓轰簡鍒ゅ畾鐢ㄦ埛璇锋眰鐨剈rl 鏄惁鍦ㄦ潈闄愯〃涓紝濡傛灉鍦ㄦ潈闄愯〃涓紝鍒欒繑鍥炵粰 decide 鏂规硶
     */

    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException 
{
        System.out.println("MyAccessDecisionManager.decide()");
        if(configAttributes == null  || configAttributes.size()==0) {
            throw new AccessDeniedException("permission denied");
        }

        ConfigAttribute cfa;
        String needRole;
        //閬嶅巻鍩轰簬URL鑾峰彇鐨勬潈闄愪俊鎭拰鐢ㄦ埛鑷韩鐨勮鑹蹭俊鎭繘琛屽姣?
        for(Iterator<ConfigAttribute> it=configAttributes.iterator();it.hasNext();) {
            cfa = it.next();
            needRole = cfa.getAttribute();
            System.out.println("decide,needRole:"+needRole+",authentication="+authentication);
            //authentication 涓篊ustomUserDetailService涓坊鍔犵殑鏉冮檺淇℃伅.
            for(GrantedAuthority grantedAuthority:authentication.getAuthorities()) {
                if(needRole.equals(grantedAuthority.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("permission denied");
    }



    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

}


1.3 鑷畾涔塅ilter

       鑷畾涔変竴涓狥ilter缁ф壙AbstractSecurityInterceptor锛屽湪杩欎釜鏂规硶閲屼富瑕佹敞鍏ユ垜浠笂闈㈢紪鍐欑殑涓や釜绫伙細
锛?锛夊畨鍏ㄤ俊鎭暟鎹簮锛歁yFilterInvocationSecurityMetadataSource

锛?锛夎闂喅绛栫鐞嗗櫒锛歁yAccessDecisionManager

鍏蜂綋浠g爜濡備笅锛?/span>

package com.kfit.config;

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;
import org.springframework.stereotype.Component;

@Component
public class MyAccessDecisionManager implements AccessDecisionManager{

    /**
     * 鏂规硶鏄垽瀹氭槸鍚︽嫢鏈夋潈闄愮殑鍐崇瓥鏂规硶锛?br>     * (1)authentication 鏄噴CustomUserService涓惊鐜坊鍔犲埌 GrantedAuthority 瀵硅薄涓殑鏉冮檺淇℃伅闆嗗悎.
     * (2)object 鍖呭惈瀹㈡埛绔彂璧风殑璇锋眰鐨剅equset淇℃伅锛屽彲杞崲涓?nbsp;HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
     * (3)configAttributes 涓篗yFilterInvocationSecurityMetadataSource鐨刧etAttributes(Object object)杩欎釜鏂规硶杩斿洖鐨勭粨鏋滐紝姝ゆ柟娉曟槸涓轰簡鍒ゅ畾鐢ㄦ埛璇锋眰鐨剈rl 鏄惁鍦ㄦ潈闄愯〃涓紝濡傛灉鍦ㄦ潈闄愯〃涓紝鍒欒繑鍥炵粰 decide 鏂规硶
     */

    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException 
{
        System.out.println("MyAccessDecisionManager.decide()");
        if(configAttributes == null  || configAttributes.size()==0) {
            throw new AccessDeniedException("permission denied");
        }

        ConfigAttribute cfa;
        String needRole;
        //閬嶅巻鍩轰簬URL鑾峰彇鐨勬潈闄愪俊鎭拰鐢ㄦ埛鑷韩鐨勮鑹蹭俊鎭繘琛屽姣?
        for(Iterator<ConfigAttribute> it=configAttributes.iterator();it.hasNext();) {
            cfa = it.next();
            needRole = cfa.getAttribute();
            System.out.println("decide,needRole:"+needRole+",authentication="+authentication);
            //authentication 涓篊ustomUserDetailService涓坊鍔犵殑鏉冮檺淇℃伅.
            for(GrantedAuthority grantedAuthority:authentication.getAuthorities()) {
                if(needRole.equals(grantedAuthority.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("permission denied");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

}

      鍒拌繖閲屽氨鍙互娴嬭瘯涓嬫晥鏋滀簡锛屽拰涔嬪墠鐨勭粨鏋滃簲璇ユ槸涓€鏍风殑銆?/span>

鍘嗗彶鏂囩珷





















鎴戝氨鏄垜锛屾槸棰滆壊涓嶄竴鏍风殑鐑熺伀銆?br class="mq-326">鎴戝氨鏄垜锛屾槸涓庝紬涓嶅悓鐨勫皬鑻规灉銆?br class="mq-327">


鎮熺┖瀛﹂櫌锛?span class="mq-331">http://t.cn/Rg3fKJD

瀛﹂櫌涓湁Spring Boot鐩稿叧鐨勮绋嬶紒鐐瑰嚮銆?/span>闃呰鍘熸枃銆嶈繘琛屾煡鐪嬶紒

SpringBoot瑙嗛锛歨ttp://t.cn/R3QepWG

Spring Cloud瑙嗛锛歨ttp://t.cn/R3QeRZc

SpringBoot Shiro瑙嗛锛歨ttp://t.cn/R3QDMbh

SpringBoot浜ゆ祦骞冲彴锛歨ttp://t.cn/R3QDhU0

SpringData鍜孞PA瑙嗛锛歨ttp://t.cn/R1pSojf

SpringSecurity5.0瑙嗛锛歨ttp://t.cn/EwlLjHh

Sharding-JDBC鍒嗗簱鍒嗚〃瀹炴垬锛歨ttp://t.cn/E4lpD6e

以上是关于251.Spring Boot+Spring Security锛氬熀浜嶶RL鍔ㄦ€佹潈闄愶細鑷畾涔塅ilter的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot启动过程:Spring Boot内嵌Tomcat启动

spring boot 之注解

Spring boot??????????????????Spring boot??????MySql,Mybatis???PageHelper??????

Spring Boot 事物回滚

使用 Spring Boot 时如何使用 SpringTemplateEngine

jboss spring boot