1. 概念

  1. Spring Security:Spring 提供的安全框架,用于保护应用程序免受未授权访问,提供认证、授权、CSRF 防护等功能。

  2. 核心功能

    • 认证(Authentication):确认用户身份(登录过程)。

    • 授权(Authorization / Access Control):控制用户访问资源的权限。

    • 安全上下文(SecurityContext):存储当前用户信息的容器。

    • 过滤器链(Filter Chain):拦截请求,按顺序执行安全逻辑。


2. 核心组件

组件 作用
UserDetailsService 用户信息服务,用于根据用户名查询用户信息(用户名、密码、权限)
UserDetails 用户信息接口(用户名、密码、权限、状态)
GrantedAuthority 用户权限/角色接口,用于授权判断
PasswordEncoder 密码加密器,如 BCryptPasswordEncoder
AuthenticationManager 认证管理器,负责执行认证逻辑
SecurityContextHolder 存储认证信息的上下文,当前线程可访问
HttpSecurity 配置 HTTP 请求安全策略(认证/授权、表单登录、CSRF 等)
FilterChainProxy 核心过滤器链,所有请求经过一系列安全过滤器处理

3. 常见配置方式(Spring Boot)

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    // 用户信息服务
    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("zhangsan")
                               .password("123")
                               .authorities("p1")
                               .build());
        manager.createUser(User.withUsername("lisi")
                               .password("456")
                               .authorities("p2")
                               .build());
        return manager;
    }

    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    // HTTP 安全配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/r/r1").hasAuthority("p1")
                .antMatchers("/r/r2").hasAuthority("p2")
                .antMatchers("/r/**").authenticated()
                .anyRequest().permitAll()
            .and()
                .formLogin()
                .successForwardUrl("/login-success"); // 登录成功后转发
    }
}

4.认证与授权流程

4.1 结构总览

         Spring Security所解决的问题就是安全访问控制,而安全访问控制功能其实就是对所有进入系统的请求进行拦截, 校验每个请求是否能够访问它所期望的资源。根据前边知识的学习,可以通过FilterAOP等技术来实现,Spring Security对Web资源的保护是靠Filter实现的,所以从这个Filter来入手,逐步深入Spring Security原理。
         当初始化Spring Security时,会创建一个名为 SpringSecurityFilterChain Servlet过滤器,类型为 org.springframework.security.web.FilterChainProxy,它实现了javax.servlet.Filter,因此外部的请求会经过此
类,下图是Spring Security过虑器链结构图:

        FilterChainProxy是一个代理,真正起作用的是FilterChainProxySecurityFilterChain所包含的各个Filter,同时 这些Filter作为BeanSpring管理,它们是Spring Security核心,各有各的职责,但他们并不直接处理用户的,也不直接处理用户的授权,而是把它们交给了认证管理器(AuthenticationManager)和决策管理器(AccessDecisionManager)进行处理,下图是FilterChainProxy相关类的UML图示。

spring Security功能的实现主要是由一系列过滤器链相互配合完成。

下面介绍过滤器链中主要的几个过滤器及其作用:
      (1)SecurityContextPersistenceFilter:
            这个Filter是整个拦截过程的入口和出口(也就是第一个和最后一个拦截 器),会在请求开始时从配置好的 SecurityContextRepository 中获取 SecurityContext,然后把它设置给 SecurityContextHolder。
           在请求完成后将 SecurityContextHolder 持有的 SecurityContext 再保存到配置好的 SecurityContextRepository,同时清除 securityContextHolder 所持有的 SecurityContext
     (2)UsernamePasswordAuthenticationFilter
            用于处理来自表单提交的认证。该表单必须提供对应的用户名和密码,其内部还有登录成功或失败后进行处理的AuthenticationSuccessHandler和 AuthenticationFailureHandler,这些都可以根据需求做相关改变;
     (3)FilterSecurityInterceptor
            是用于保护web资源的,使用AccessDecisionManager对当前用户进行授权访问,前面已经详细介绍过了;
    (4)ExceptionTranslationFilter
           能够捕获来自 FilterChain 所有的异常,并进行处理。但是它只会处理两类异常:
AuthenticationException AccessDeniedException,其它的异常它会继续抛出。

4.2 认证(Authentication)流程

  1. 用户提交登录请求(POST /login 或表单提交)。

  2. UsernamePasswordAuthenticationFilter 拦截请求。

  3. AuthenticationManager 调用 ProviderManager

  4. AuthenticationProvider 使用 UserDetailsService 加载用户信息。

  5. PasswordEncoder 验证密码是否匹配。

  6. 如果验证成功:

    • 创建 Authentication 对象(包含用户名、权限)。

    • 保存到 SecurityContextHolder 中。

  7. 登录成功,执行 successHandlersuccessForwardUrl

图示

用户登录请求 → UsernamePasswordAuthenticationFilter → AuthenticationManager → AuthenticationProvider → UserDetailsService → 密码验证 → SecurityContextHolder 保存用户信息 → 登录成功处理

图解以及解析

让我们仔细分析认证过程:


4.3 授权(Authorization)流程

  1. 请求到达 Controller 前,由 FilterSecurityInterceptor 处理。

  2. 获取当前用户的 Authentication(从 SecurityContextHolder)。

  3. 对比请求资源的 权限配置(如 .antMatchers("/r/r1").hasAuthority("p1"))。

  4. 判断用户是否拥有访问权限:

    • 有权限 → 放行,访问 Controller 方法。

    • 无权限 → 拦截,返回 403 或跳转到 Access Denied 页面。

  5. Controller 执行完毕,视图渲染返回响应。

图示

HTTP 请求 → FilterSecurityInterceptor → SecurityContextHolder 获取 Authentication → 对比权限 → 放行/拒绝 → Controller 方法执行 → 返回响应

图解以及解析

分析授权流程:

5. 权限控制方式

  1. 基于 URL 的权限控制(HttpSecurity 配置)

    • .antMatchers("/r/r1").hasAuthority("p1")

  2. 基于方法的权限控制(Spring 方法级安全)

    • @PreAuthorize("hasAuthority('p1')")

    • @Secured("ROLE_ADMIN")

    • 注意:使用上面两种方法权限,需要在配置类(WebSecurityConfig)上加@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)


6. 常见注意事项

  1. UserDetailsService 只负责查询用户信息,不负责认证逻辑。

  2. PasswordEncoder 必须与存储密码一致,否则密码匹配失败。

  3. successForwardUrl → 服务器内部转发,需要自己提供对应 Controller 或页面。

  4. authenticated()hasAuthority() 的区别:

    • authenticated() → 已登录即可访问

    • hasAuthority("p1") → 必须具备指定权限才能访问

  5. Spring Boot 引入 spring-boot-starter-security → 默认启用 Security,无需 @EnableWebSecurity(除非想自定义配置)。


总结流程

  • 认证:用户身份验证 → 创建 Authentication → 保存到 SecurityContextHolder

  • 授权:访问请求 → 检查 Authentication 权限 → 放行/拒绝

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐