当前位置: 代码网 > it编程>编程语言>Java > Java中AuthorizationFilter过滤器的功能

Java中AuthorizationFilter过滤器的功能

2026年02月10日 Java 我要评论
authorizationfilter过滤器的作用在 spring security 框架中,authorizationfilter 是负责执行授权(authorization) 决策的核心过滤器。根

authorizationfilter过滤器的作用

在 spring security 框架中,authorizationfilter 是负责执行授权(authorization) 决策的核心过滤器。根据当前的 authentication(认证信息)和请求上下文,判断当前用户是否有权限访问目标资源。

先看段源码

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 {
         //授权决策
         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 本身不直接做授权判断,而是委托给一个 authorizationmanager 接口.

authorizationmanager

从上面的代码中可以看出,授权的核心在于调用authorizationmanager的check方法,去决定当前的authentication是否有权限访问request

//授权决策
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方法,为什么说叫授权决策,因为check方法返回的是authorizationdecision,这是一种授权结果 里面有个字段granted,用来决定是否有权限继续访问当前资源。

    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

如果你去调试你会发现authorizationfilter委托的authorizationmanager的实现类是 requestmatcherdelegatingauthorizationmanager,至于为什么是这个实现类,我们后续会出一个文章专门来讲解,大体还是httpsecurity,因为它就是用来配置过滤器链的,底层就是配置过滤器的。这里不会多讲。拆解一下这个类的名字

  • requestmatcher:请求匹配器,用于匹配不同的 http 请求(如 /admin/**, /public/**)
  • delegating:代表“委派”,即它自己不做判断,而是把任务委派给其他具体的 authorizationmanager
  • authorizationmanager:授权管理接口,负责做出“允许”或“拒绝”的决策

requestmatcherdelegatingauthorizationmanager 内部维护了一个列表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和其他对象建立关联的
 * @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中的每个条目requestmatcherentry代表着一种映射关系,里面包含了

  • 一个 requestmatcher(比如 antpathrequestmatcher("/admin/**", "get"))
  • 一个对应的 authorizationmanager(比如负责判断 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的核心流程是:当请求到来时,它会:

  • 遍历这个列表,取出里面的每个requestmatcher,然后去判断当前requestmatcher是否和当前请求request匹配,找到匹配后,找到和requestmatcher匹配的authorizationmanager
  • 将授权任务委托给该条目对应的 authorizationmanager
  • 如果没有任何匹配,默认拒绝(或使用默认策略)。

mappings列表中注册的requestmatcher和authorizationmanager关系是如何绑定的

后续我会专门出一期文章从源码角度讲解requestmatcherdelegatingauthorizationmanager是如何完成创建以及初始化mappings的,这里我们会如何使用就好啦。我们经常在配置过滤器链的时候有如下配置

@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映射关系,也就是当访问/admin/**时,底层会创建一个authorityauthorizationmanager来处理授权决策(这块后面出一篇文章细讲),.hasrole("admin")底层会创建一个authorizationmanager来处理授权请求。

授权结果

从 authorizationfilter的源码中我们知道,如果授权没通过的话就会抛出一个accessdeniedexception异常,这个异常通常会被exceptiontranslationfilter过滤器捕获 然后进行处理,这个我们后续再将

    if (decision != null && !decision.isgranted()) { throw new accessdeniedexception("access denied"); }

总结

authorizationfilter过滤器是用来实现授权决策的,但是它会委托给 requestmatcherdelegatingauthorizationmanager来实现具体的授权决策,结合当前请求和authentication来决定是否有权限。但是这里我也留下了几处坑,没有填,后续我会写文章继续填坑

  1. authorizationfilter里面的requestmatcherdelegatingauthorizationmanager是什么时候配置的
  2. requestmatcherdelegatingauthorizationmanager需要维护一个mappings,用来映射requestmatcher和authorizationmanager
  3. 用户配置调用的requestmatchers("/admin/**").hasrole("admin") 等配置,最后怎么生效的,底层原理是什么 4.授权没通过抛出的异常被 exceptiontranslationfilter捕获后如何自定义处理。

到此这篇关于java中authorizationfilter过滤器的功能的文章就介绍到这了,更多相关java authorizationfilter过滤器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com