Spring Security(一)架构概览

一、 Spring Security 架构概览

1. Spring Security 简介

在Java企业级开发中,安全管理方面的框架非常少,一般来说,主要是三种方案:

  • Shiro
  • Spring Security
  • 开发者自己实现

Spring Security基于Spring框架,提供了一套Web应用安全性的完整解决方案。一般来说,Web应用的安全性包括用户认证 (Authentication)和用户授权(Authorization)两个部分。

2. Spring Security 核心功能

1)用户认证 (Authentication)

用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。

Spring Security集成的主流认证机制包括:

  • 表单认证
  • OAuth2.0
  • CAS认证
  • RememberMe自动认证
  • ...
2)**用户授权 (Authorization) **

用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

3)其他

Spring Security 还提供了很多按钮全管理的"周边功能",例如,CSRF攻击、会话固定攻击等,同时Spring Security 还提供了 HTTP 防火墙来拦截大量的非法请求。

3. Spring Security 整体框架

1)认证

在 Spring Security 中,用户的认证信息主要由 Authentication 的实现类来保存,Authentication 接口定义如下:

java 复制代码
public interface Authentication extends Principal, Serializable {
    // 用来获取用户的权限
    Collection<? extends GrantedAuthority> getAuthorities();
    // 用来获取用户凭证,一般来说就是密码
    Object getCredentials();
	// 用来获取用户携带的详细信息,可能是当前请求之类等
    Object getDetails();
	// 有用来获取当前用户,例如一个用户名或者一个用户对象
    Object getPrincipal();
	// 当前用户是否认证成功
    boolean isAuthenticated();

    void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

当用户使用用户名/密码登录或者使用 Remember-me 登录时,都会对应一个不同的 Authentication 实例。

Spring Security 中的认证工作主要是由 AuthenticationManager接口来负责:

java 复制代码
public interface AuthenticationManager {
    /** AuthenticationManager 只有一个 authenticate 方法可以用来做认证,该方法有三个不同的返回值:
    *   1. 返回 Authentication,表示认证成功
    *   2. 抛出 AuthenticationException 异常,表示用户输入了无效的凭证。
    *   3. 返回null,表示不能断定。
    */  
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
}

在介绍了 AuthenticationManager 之后,我们介绍 AuthenticationManager 的主要实现类 ProviderManager,ProviderManager 管理了众多的 AuthenticationProvider 实例。

java 复制代码
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
    private List<AuthenticationProvider> providers;
    
    public ProviderManager(AuthenticationProvider... providers) {
        this(Arrays.asList(providers), (AuthenticationManager)null);
    }
    
    public ProviderManager(List<AuthenticationProvider> providers, AuthenticationManager parent) {
        this.eventPublisher = new NullEventPublisher();
        this.providers = Collections.emptyList();
        this.messages = SpringSecurityMessageSource.getAccessor();
        this.eraseCredentialsAfterAuthentication = true;
        Assert.notNull(providers, "providers list cannot be null");
        this.providers = providers;
        this.parent = parent;
        this.checkState();
    }
}
java 复制代码
public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
	// supports 方法用来判断是否支持给定的 Authentication 类型
    boolean supports(Class<?> authentication);
}

由于 Authentication 拥有众多的实现类,这些不同的实现类又有不同的 AuthenticationProvider 来处理,所以 AuthenticationProvider 会有一个 supports 方法来判断当前的 AuthenticationProvider 是否支持对应的 Authentication。

再一次完整的认证过程中,可能会存在多个 AuthenticationProvider (比如一个项目同时存在form表单登录和短信验证码登录),多个AuthenticationProvider 统一由 ProviderManager 来管理。如果所有的 AuthenticationProvider 都认证失败了,那么就会电泳 parent 进行认证,相当于是一个备用认证方式。

2)授权

在 Sping Security 的授权体系中,有两个关键接口:

  • AccessDecisionManager

    它是一个决策器,来决定此次访问是否被允许。

  • AccessDecisionVoter

    它是一个投票器,投票器会检查用户是否具备应有的角色,进而投出赞成、反对或弃权。

它们都有众多的实现类,在 AccessDecisionManager 会挨个访问 AccessDecisionVoter,进而决定是否允许用户访问,因此,AccessDecisionVoter 和 AccessDecisionManager 的关系似于 AuthenticationProvider 和 ProviderManager 之间的关系。

3)Web安全

在 Spring Security 中,认证和授权都是基于过滤器来完成的。这些过滤器按照既定的优先级排列,最终形成一个过滤器链。开发者也可以通过自定义过滤器,并通过@Order注解来调整自定义过滤器在过滤器链中的位置,并通过FiliterChainProxy来统一管理。Spring Security 中的过滤器链通过FiliterChainProxy 嵌入到 Web 项目的原生过滤器链中。

4) 登录数据保护

当用户登录成功后,Spring Security会将登录成功的用户信息保存到 SecurityContextHolder 中。存入其中的数据默认通过ThreadLocal 来实现的。用户数据是和当前请求线程绑定在一起的。当登录请求处理完毕后, Spring Security 会将 SecurityContextHolder 中的数据拿出来保存到Session 中, 同时,将 SecurityContextHolder 中的数据清空。

《深入浅出 Spring Security》 王松 著

相关推荐
仙俊红9 小时前
spring的IoC(控制反转)面试题
java·后端·spring
阿湯哥9 小时前
AgentScope Java 集成 Spring AI Alibaba Workflow 完整指南
java·人工智能·spring
廋到被风吹走9 小时前
【Spring】Spring Cloud 熔断降级深度解析:从 Hystrix 到 Resilience4j 的演进
spring·spring cloud·hystrix
fenglllle10 小时前
spring-data-jpa saveall慢的原因
数据库·spring·hibernate
czlczl2002092510 小时前
Guava Cache 原理与实战
java·后端·spring
阿湯哥13 小时前
Spring AI Alibaba 实现 Workflow 全指南
java·人工智能·spring
萧曵 丶15 小时前
Spring Cloud Alibaba 详解
spring·spring cloud
szm022516 小时前
Spring
java·后端·spring
萧曵 丶17 小时前
Spring 全套高频面试题(由浅到深 完整版)
java·后端·spring
雨中飘荡的记忆19 小时前
Spring Security入门:构建安全应用
spring