Spring Security6 教程

AuthenticatedAuthorizationManager 授权管理器

AuthenticatedAuthorizationManager 类基于用户认证状态进行授权决策。如当前用户是否匿名、是否通过完整认证(即用户名/密码登陆)、是否通过“记住我”认证),适用于需要区分不同登录级别访问权限的场景。

核心方法

AuthenticatedAuthorizationManager 类提供的核心方法如下:

  • authenticated()   允许所有认证用户访问,包括:完整认证用户(通过用户名 / 密码等常规方式登录)、记住我认证用户。但是,会拒绝匿名用户(未认证的用户)。

  • fullyAuthenticated()   仅允许完整认证的用户进行访问,即通过用户名 / 密码、OAuth2 等主动登录流程认证的用户。会拒绝匿名用户和记住我的认证用户。

  • anonymous()  仅允许匿名用户访问,即未进行任何认证的用户。拒绝所有已认证用户(包括完整认证和“记住我”认证用户)。

  • rememberMe()  允许“记住我”和完整认证的用户访问,但逻辑更倾向于“记住我”场景。

源码分析

package org.springframework.security.authorization;

import java.util.function.Supplier;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;

public final class AuthenticatedAuthorizationManager<T> implements AuthorizationManager<T> {
    private final AbstractAuthorizationStrategy authorizationStrategy;

    //...

    /**
     * 创建 AuthenticatedAuthorizationManager 的实例。
     */
    public static <T> AuthenticatedAuthorizationManager<T> authenticated() {
       return new AuthenticatedAuthorizationManager<>();
    }

    /**
     * 创建 AuthenticatedAuthorizationManager 的一个实例,用于确定是否在不使用记住我的情况下进行身份验证。
     */
    public static <T> AuthenticatedAuthorizationManager<T> fullyAuthenticated() {
       return new AuthenticatedAuthorizationManager<>(new FullyAuthenticatedAuthorizationStrategy());
    }

    /**
     * 创建 AuthenticatedAuthorizationManager 的实例,该实例可确定身份验证是否使用 “记住我 ”进行验证。
     */
    public static <T> AuthenticatedAuthorizationManager<T> rememberMe() {
       return new AuthenticatedAuthorizationManager<>(new RememberMeAuthorizationStrategy());
    }

    /**
     * 创建 AuthenticatedAuthorizationManager 的实例,用于确定 Authentication 是否匿名。
     */
    public static <T> AuthenticatedAuthorizationManager<T> anonymous() {
       return new AuthenticatedAuthorizationManager<>(new AnonymousAuthorizationStrategy());
    }

    /**
     * 根据给定的策略确定当前用户是否获得授权。
     * @param authentication the {@link Supplier} of the {@link Authentication} to check
     * @param object the {@link T} object to check
     * @return an {@link AuthorizationDecision}
     */
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
       // 调用 AbstractAuthorizationStrategy 类的 isGranted() 方法
       boolean granted = this.authorizationStrategy.isGranted(authentication.get());
       return new AuthorizationDecision(granted);
    }
    
    //...
}

AbstractAuthorizationStrategy 类的 isGranted() 方法,源码如下:

private static class AuthenticatedAuthorizationStrategy extends AbstractAuthorizationStrategy {

    @Override
    boolean isGranted(Authentication authentication) {
       return this.trustResolver.isAuthenticated(authentication);
    }

}

AuthenticationTrustResolver 接口 isAuthenticated() 方法,源码如下:

/**
 * 检查 Authentication 是否为空值、已验证且非匿名。
 * @param authentication the {@link Authentication} to check.
 * @return true if the {@link Authentication} is not null,
 * {@link #isAnonymous(Authentication)} returns false, &
 * {@link Authentication#isAuthenticated()} is true.
 * @since 6.1.7
 */
default boolean isAuthenticated(Authentication authentication) {
    return authentication != null && authentication.isAuthenticated() && !isAnonymous(authentication);
}

简单示例

通过静态方法,创建 AuthenticatedAuthorizationManager 类的示例,如下:

// 验证用户是否已认证(包括记住我用户)
AuthenticatedAuthorizationManager.authenticated();

// 验证用户是否为完全认证(非记住我用户)
AuthenticatedAuthorizationManager.fullyAuthenticated();

// 验证用户是否通过记住我功能认证
AuthenticatedAuthorizationManager.rememberMe();

// 验证用户是否为匿名用户
AuthenticatedAuthorizationManager.anonymous();

在 access() 方法中通过 AuthenticatedAuthorizationManager  类进行配置,如下:

http.authorizeHttpRequests(authorize -> authorize
    // 允许匿名访问 /sys 路径
    .requestMatchers("/sys/**").access(AuthenticatedAuthorizationManager.anonymous())
    .anyRequest().authenticated() // 其他请求需认证
)


说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号