最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中AuthorizationFilter過濾器的功能

 更新時(shí)間:2026年02月10日 10:21:00   作者:MrSYJ  
本文主要介紹了Java中AuthorizationFilter過濾器的功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

AuthorizationFilter過濾器的作用

在 Spring Security 框架中,AuthorizationFilter 是負(fù)責(zé)執(zhí)行授權(quán)(Authorization) 決策的核心過濾器。根據(jù)當(dāng)前的 Authentication(認(rèn)證信息)和請(qǐng)求上下文,判斷當(dāng)前用戶是否有權(quán)限訪問目標(biāo)資源。

先看段源碼

public class AuthorizationFilter extends GenericFilterBean {

   ...
   private final AuthorizationManager<HttpServletRequest> authorizationManager;

   

   /**
    * Creates an instance.
    * @param authorizationManager the {@link AuthorizationManager} to use
    */
   public AuthorizationFilter(AuthorizationManager<HttpServletRequest> authorizationManager) {
      Assert.notNull(authorizationManager, "authorizationManager cannot be null");
      this.authorizationManager = authorizationManager;
   }

   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
         throws ServletException, IOException {

      HttpServletRequest request = (HttpServletRequest) servletRequest;
      HttpServletResponse response = (HttpServletResponse) servletResponse;

      if (this.observeOncePerRequest && isApplied(request)) {
         chain.doFilter(request, response);
         return;
      }

      if (skipDispatch(request)) {
         chain.doFilter(request, response);
         return;
      }

      String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
      request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
      try {
         //授權(quán)決策
         AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
         this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);
         if (decision != null && !decision.isGranted()) {
            throw new AccessDeniedException("Access Denied");
         }
         chain.doFilter(request, response);
      }
      finally {
         request.removeAttribute(alreadyFilteredAttributeName);
      }
   }

從上面的代碼中可以看出:AuthorizationFilter 本身不直接做授權(quán)判斷,而是委托給一個(gè) AuthorizationManager 接口.

AuthorizationManager

從上面的代碼中可以看出,授權(quán)的核心在于調(diào)用authorizationManager的check方法,去決定當(dāng)前的authentication是否有權(quán)限訪問request

//授權(quán)決策
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
@FunctionalInterface
public interface AuthorizationManager<T> {

   /**
    * Determines if access should be granted for a specific authentication and object.
    * @param authentication the {@link Supplier} of the {@link Authentication} to check
    * @param object the {@link T} object to check
    * @throws AccessDeniedException if access is not granted
    */
   default void verify(Supplier<Authentication> authentication, T object) {
      AuthorizationDecision decision = check(authentication, object);
      if (decision != null && !decision.isGranted()) {
         throw new AccessDeniedException("Access Denied");
      }
   }

   /**
    * Determines if access is granted for a specific authentication and object.
    * @param authentication the {@link Supplier} of the {@link Authentication} to check
    * @param object the {@link T} object to check
    * @return an {@link AuthorizationDecision} or null if no decision could be made
    */
   @Nullable
   AuthorizationDecision check(Supplier<Authentication> authentication, T object);

}

AuthorizationManager接口定義了check方法,為什么說叫授權(quán)決策,因?yàn)閏heck方法返回的是AuthorizationDecision,這是一種授權(quán)結(jié)果 里面有個(gè)字段granted,用來決定是否有權(quán)限繼續(xù)訪問當(dāng)前資源。

    public class AuthorizationDecision implements AuthorizationResult {

   private final boolean granted;

   public AuthorizationDecision(boolean granted) {
      this.granted = granted;
   }

   @Override
   public boolean isGranted() {
      return this.granted;
   }

   @Override
   public String toString() {
      return getClass().getSimpleName() + " [granted=" + this.granted + "]";
   }

}
    

RequestMatcherDelegatingAuthorizationManager

如果你去調(diào)試你會(huì)發(fā)現(xiàn)AuthorizationFilter委托的AuthorizationManager的實(shí)現(xiàn)類是 RequestMatcherDelegatingAuthorizationManager,至于為什么是這個(gè)實(shí)現(xiàn)類,我們后續(xù)會(huì)出一個(gè)文章專門來講解,大體還是HttpSecurity,因?yàn)樗褪怯脕砼渲眠^濾器鏈的,底層就是配置過濾器的。這里不會(huì)多講。拆解一下這個(gè)類的名字

  • RequestMatcher:請(qǐng)求匹配器,用于匹配不同的 HTTP 請(qǐng)求(如 /admin/**, /public/**)
  • Delegating:代表“委派”,即它自己不做判斷,而是把任務(wù)委派給其他具體的 AuthorizationManager
  • AuthorizationManager:授權(quán)管理接口,負(fù)責(zé)做出“允許”或“拒絕”的決策

RequestMatcherDelegatingAuthorizationManager 內(nèi)部維護(hù)了一個(gè)列表mappings:

public final class RequestMatcherDelegatingAuthorizationManager implements AuthorizationManager<HttpServletRequest> {

   private static final AuthorizationDecision DENY = new AuthorizationDecision(false);

   private final List<RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>>> mappings;
/**
 * A rich object for associating a {@link RequestMatcher} to another object.
 * 從注釋中可以看出RequestMatcherEntry就是用來將RequestMatcher和其他對(duì)象建立關(guān)聯(lián)的
 * @author Marcus Da Coregio
 * @since 5.5.5
 */
public class RequestMatcherEntry<T> {

   private final RequestMatcher requestMatcher;

   private final T entry;

   public RequestMatcherEntry(RequestMatcher requestMatcher, T entry) {
      this.requestMatcher = requestMatcher;
      this.entry = entry;
   }

   public RequestMatcher getRequestMatcher() {
      return this.requestMatcher;
   }

   public T getEntry() {
      return this.entry;
   }

}

mappings中的每個(gè)條目RequestMatcherEntry代表著一種映射關(guān)系,里面包含了

  • 一個(gè) RequestMatcher(比如 AntPathRequestMatcher("/admin/**", "GET"))
  • 一個(gè)對(duì)應(yīng)的 AuthorizationManager(比如負(fù)責(zé)判斷 hasRole('ADMIN') 的管理器)

接下來我們看下RequestMatcherDelegatingAuthorizationManager的check流程

/**
 * Delegates to a specific {@link AuthorizationManager} based on a
 * {@link RequestMatcher} evaluation.
 * @param authentication the {@link Supplier} of the {@link Authentication} to check
 * @param request the {@link HttpServletRequest} to check
 * @return an {@link AuthorizationDecision}. If there is no {@link RequestMatcher}
 * matching the request, or the {@link AuthorizationManager} could not decide, then
 * null is returned
 */
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, HttpServletRequest request) {
   if (this.logger.isTraceEnabled()) {
      this.logger.trace(LogMessage.format("Authorizing %s", requestLine(request)));
   }
   for (RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>> mapping : this.mappings) {

      RequestMatcher matcher = mapping.getRequestMatcher();
      MatchResult matchResult = matcher.matcher(request);
      if (matchResult.isMatch()) {
         AuthorizationManager<RequestAuthorizationContext> manager = mapping.getEntry();
         if (this.logger.isTraceEnabled()) {
            this.logger.trace(
                  LogMessage.format("Checking authorization on %s using %s", requestLine(request), manager));
         }
         return manager.check(authentication,
               new RequestAuthorizationContext(request, matchResult.getVariables()));
      }
   }
   if (this.logger.isTraceEnabled()) {
      this.logger.trace(LogMessage.of(() -> "Denying request since did not find matching RequestMatcher"));
   }
   return DENY;
}

從上面的代碼我們可以看出check的核心流程是:當(dāng)請(qǐng)求到來時(shí),它會(huì):

  • 遍歷這個(gè)列表,取出里面的每個(gè)RequestMatcher,然后去判斷當(dāng)前RequestMatcher是否和當(dāng)前請(qǐng)求request匹配,找到匹配后,找到和RequestMatcher匹配的AuthorizationManager
  • 將授權(quán)任務(wù)委托給該條目對(duì)應(yīng)的 AuthorizationManager。
  • 如果沒有任何匹配,默認(rèn)拒絕(或使用默認(rèn)策略)。

mappings列表中注冊(cè)的RequestMatcher和AuthorizationManager關(guān)系是如何綁定的

后續(xù)我會(huì)專門出一期文章從源碼角度講解RequestMatcherDelegatingAuthorizationManager是如何完成創(chuàng)建以及初始化mappings的,這里我們會(huì)如何使用就好啦。我們經(jīng)常在配置過濾器鏈的時(shí)候有如下配置

@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
        throws Exception {
    System.out.println("filterChain http: " + System.identityHashCode(http));
    http
            .authorizeHttpRequests((authorize) -> authorize
                    .requestMatchers("/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated()
            );
           

    return http.build();
}

比如這句代碼.requestMatchers("/admin/**").hasRole("ADMIN")就是在配置mappings映射關(guān)系,也就是當(dāng)訪問/admin/**時(shí),底層會(huì)創(chuàng)建一個(gè)AuthorityAuthorizationManager來處理授權(quán)決策(這塊后面出一篇文章細(xì)講),.hasRole("ADMIN")底層會(huì)創(chuàng)建一個(gè)AuthorizationManager來處理授權(quán)請(qǐng)求。

授權(quán)結(jié)果

從 AuthorizationFilter的源碼中我們知道,如果授權(quán)沒通過的話就會(huì)拋出一個(gè)AccessDeniedException異常,這個(gè)異常通常會(huì)被ExceptionTranslationFilter過濾器捕獲 然后進(jìn)行處理,這個(gè)我們后續(xù)再將

    if (decision != null && !decision.isGranted()) { throw new AccessDeniedException("Access Denied"); }

總結(jié)

AuthorizationFilter過濾器是用來實(shí)現(xiàn)授權(quán)決策的,但是它會(huì)委托給 RequestMatcherDelegatingAuthorizationManager來實(shí)現(xiàn)具體的授權(quán)決策,結(jié)合當(dāng)前請(qǐng)求和authentication來決定是否有權(quán)限。但是這里我也留下了幾處坑,沒有填,后續(xù)我會(huì)寫文章繼續(xù)填坑

  1. AuthorizationFilter里面的RequestMatcherDelegatingAuthorizationManager是什么時(shí)候配置的
  2. RequestMatcherDelegatingAuthorizationManager需要維護(hù)一個(gè)mappings,用來映射requestMatcher和authorizationManager
  3. 用戶配置調(diào)用的requestMatchers("/admin/**").hasRole("ADMIN") 等配置,最后怎么生效的,底層原理是什么 4.授權(quán)沒通過拋出的異常被 ExceptionTranslationFilter捕獲后如何自定義處理。

到此這篇關(guān)于Java中AuthorizationFilter過濾器的功能的文章就介紹到這了,更多相關(guān)Java AuthorizationFilter過濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot如何連接兩個(gè)數(shù)據(jù)庫(多個(gè))

    springboot如何連接兩個(gè)數(shù)據(jù)庫(多個(gè))

    這篇文章主要介紹了springboot如何連接兩個(gè)數(shù)據(jù)庫(多個(gè)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法示例

    Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法示例

    這篇文章主要介紹了Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法,結(jié)合實(shí)例形式分析了Java使用遞歸與循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積相關(guān)概念、原理與操作技巧,需要的朋友可以參考下
    2017-12-12
  • Sentinel 斷路器在Spring Cloud使用詳解

    Sentinel 斷路器在Spring Cloud使用詳解

    Sentinel是阿里巴巴開源的一款微服務(wù)流量控制組件,主要以流量為切入點(diǎn),從流量路由、流量控制、流量整形、熔斷降級(jí)、系統(tǒng)自適應(yīng)過載保護(hù)、熱點(diǎn)流量防護(hù)等多個(gè)維度來幫助開發(fā)者保障微服務(wù)的穩(wěn)定性,本文介紹Sentinel 斷路器在Spring Cloud使用,感興趣的朋友一起看看吧
    2025-02-02
  • Java實(shí)現(xiàn)簡(jiǎn)單的萬年歷

    Java實(shí)現(xiàn)簡(jiǎn)單的萬年歷

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的萬年歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Java Lambda和Stream開發(fā)中20個(gè)高頻錯(cuò)誤案例分析與避坑指南

    Java Lambda和Stream開發(fā)中20個(gè)高頻錯(cuò)誤案例分析與避坑指南

    本篇文章將聚焦開發(fā)中最常見、最高頻的20個(gè)問題(含語法、函數(shù)式接口、Stream流、方法引用、并行流5大模塊),每個(gè)問題都配套問題描述+錯(cuò)誤案例+原因分析+正確解法,希望對(duì)大家有所幫助
    2026-04-04
  • Java內(nèi)存模型詳解

    Java內(nèi)存模型詳解

    JMM全稱Java Memory Model, 中文翻譯Java內(nèi)存模型,一種符合內(nèi)存模型規(guī)范的,屏蔽了各種硬件和操作系統(tǒng)的訪問差異的,本詳細(xì)介紹了Java內(nèi)存模型,感興趣的同學(xué)可以參考一下
    2023-04-04
  • Java9中接口的私有方法詳解

    Java9中接口的私有方法詳解

    印象中Java?接口就沒有論述私有方法這回事。既然?Java?9?添加了這項(xiàng)特性,那么,應(yīng)該就有它的用途,我們一起來看看?Java?9?中的接口的私有方法是什么樣的吧
    2023-04-04
  • Java深入分析講解反射機(jī)制

    Java深入分析講解反射機(jī)制

    反射是框架的靈魂,Java框架底層都是用反射機(jī)制+xml配置等來實(shí)現(xiàn)的,本文將通過示例詳細(xì)講解Java中的反射機(jī)制,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-06-06
  • 實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之整合Swagger2到通用模塊

    實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之整合Swagger2到通用模塊

    這篇文章主要為大家介紹了實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之整合Swagger2到通用模塊,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 使用SpringBoot集成Redis實(shí)現(xiàn)CRUD功能

    使用SpringBoot集成Redis實(shí)現(xiàn)CRUD功能

    本文主要介紹了使用SpringBoot集成Redis實(shí)現(xiàn)CRUD功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-10-10

最新評(píng)論

石家庄市| 大埔县| 江源县| 巴中市| 朝阳县| 哈密市| 西青区| 吕梁市| 铁力市| 科尔| 罗源县| 珠海市| 宝应县| 汾西县| 崇信县| 贞丰县| 芦溪县| 锦州市| 和田市| 祁门县| 娄烦县| 广州市| 图木舒克市| 微山县| 正定县| 德化县| 苏尼特右旗| 华坪县| 沈阳市| 清新县| 密云县| 宜章县| 三都| 永康市| 纳雍县| 新营市| 庐江县| 札达县| 五峰| 响水县| 上蔡县|