• 【Spring Security 系列】(三)剖析基础组件之授权功能


    Spring Security

    架构:https://spring.io/guides/topicals/spring-security-architecture
    文档:https://docs.spring.io/spring-security/site/docs/5.3.13.RELEASE/reference/html5/

    谈到应用安全框架就离不开两个核心功能:认证(Authentication)、授权(Authorization)。

    1. 认证
      解决 “你是谁?” 的问题。常用的认证方式就是用户登录验证。
    2. 授权
      解决 “你能干什么?” 的问题。

    上篇文章已经介绍了认证功能,本文续接上文,继续介绍授权功能。

    授权(Authorization)

    通常"授权"也被称为"权限控制"(Access Control),为了便于理解,经常又称之为鉴权。

    鉴权需要在真正逻辑之前处理,整个流程就涉及:权限信息的获取、判断是否有权限、权限不足的处理、匿名访问的处理。
    注意,匿名访问不同于权限不足,匿名访问指的是没有经过认证就访问接口,权限不足指的是用户通过认证了,但是没有访问该接口的权限。

    同样的,下面介绍 Spring Security 对上述的功能点是如何设计的。

    鉴权拦截器

    Spring Security设计了 FilterSecurityInterceptor 过滤器来执行鉴权的逻辑。

    权限信息查询

    Spring Security设计了 GrantedAuthority 接口来定义权限信息,其接口定义如下:

    public interface GrantedAuthority extends Serializable {
        String getAuthority();
    }
    
    • 1
    • 2
    • 3

    GrantedAuthority只是用来定义权限信息,那它是从哪里获取的呢?
    其实在上文中我们已经提到 UserDetailsService,其loadUserByUsername方法返回值为 UserDetails,而其中定义的 Collection getAuthorities(); 正是返回权限信息列表。
    可见在获取用户信息时,需要将权限信息一并获取,并组装到 UserDetails 中。

    判断是否有权限

    Spring Security设计了 AccessDecisionVoter 接口用于判断是否有权限(鉴权),其接口定义如下:

    public interface AccessDecisionVoter<S> {
        int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);
    }
    
    • 1
    • 2
    • 3

    vote 方法定义了鉴权逻辑,当鉴权通过时返回 1,鉴权不通过时返回 -1,不参与判断(弃权)则返回0。

    内置多个实现,有接口维度鉴权的实现:WebExpressionVoter
    也有方法维度鉴权的实现: RoleVoterAuthenticatedVoter(用于处理 @Secured 权限注解)、PreInvocationAuthorizationAdviceVoter(用于处理 @PreAuthorize 权限注解)等等

    权限不足的处理

    Spring Security设计了 AccessDeniedHandler 接口来定义权限不足的处理逻辑,其接口定义如下:

    public interface AccessDeniedHandler {
        void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException;
    }
    
    • 1
    • 2
    • 3

    匿名访问的处理

    Spring Security设计了 AuthenticationEntryPoint 接口来定义匿名访问的处理逻辑,其接口定义如下:

    public interface AuthenticationEntryPoint {
        void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException;
    }
    
    • 1
    • 2
    • 3

    end

  • 相关阅读:
    基于SSM的医院挂号管理系统
    Jvm上如何运行其他语言?JSR223规范最详细讲解
    Linux 磁盘挂载 磁盘卸载
    数组更新检测
    Tomcat部署及优化
    Java高级-stream流
    【linux】nmon 工具使用
    python学习05-协程
    移动端适配-(postcss-pxtorem)
    什么是网络编程?
  • 原文地址:https://blog.csdn.net/qq_31772441/article/details/126214014