SpringSecurity核心源码剖析+jwt+OAuth(一):SpringSecurity的初次邂逅(概念、认证、授权)

SpringSecurity 核心概念

SpringSecurity 是一个功能强大且高度可定制的身份验证和访问控制框架,专注于为 Java 应用程序提供安全性。其核心功能围绕身份验证(Authentication)和授权(Authorization)展开。

身份验证是确认用户身份的过程,通常通过用户名密码、OAuth2、JWT 等方式实现。授权是确定已验证用户拥有哪些权限,例如访问特定资源或执行某些操作。

认证流程剖析

SpringSecurity 的认证流程主要由一系列过滤器链组成。核心过滤器包括 UsernamePasswordAuthenticationFilter(处理表单登录)、BasicAuthenticationFilter(处理 HTTP Basic 认证)等。认证过程最终由 AuthenticationManager 协调,委托给 ProviderManager 和具体的 AuthenticationProvider 实现。

认证成功后,会生成 Authentication 对象并存入 SecurityContextHolder,供后续授权流程使用。默认使用 ThreadLocal 存储安全上下文,确保线程安全。

授权机制解析

授权通过 AccessDecisionManager 实现,核心策略包括:

  • 基于投票的 AffirmativeBased(一票通过即可)
  • 一致性通过的 UnanimousBased(全部投票通过)
  • 多数通过的 ConsensusBased

权限判断通常使用 hasRole()hasAuthority() 等表达式,或通过注解如 @PreAuthorize 实现方法级安全控制。配置示例:

java 复制代码
http.authorizeRequests()
    .antMatchers("/admin/**").hasRole("ADMIN")
    .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
    .anyRequest().authenticated();

JWT 集成实践

JWT(JSON Web Token)是一种无状态的认证方案,适合分布式系统。集成步骤:

创建 JWT 工具类处理令牌生成/验证:

java 复制代码
public class JwtTokenUtil {
    private String secret = "your-secret-key";
    
    public String generateToken(UserDetails userDetails) {
        return Jwts.builder()
            .setSubject(userDetails.getUsername())
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 3600*1000))
            .signWith(SignatureAlgorithm.HS512, secret)
            .compact();
    }
    
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
}

配置 JWT 过滤器:

java 复制代码
public class JwtRequestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                  HttpServletResponse response, 
                                  FilterChain chain) {
        String token = extractToken(request);
        if (token != null && jwtUtil.validateToken(token, userDetails)) {
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        chain.doFilter(request, response);
    }
}

OAuth2 集成方案

SpringSecurity 提供完整的 OAuth2 支持,包括客户端和资源服务器配置:

资源服务器配置示例:

java 复制代码
@EnableResourceServer
@Configuration
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/**").authenticated();
    }
    
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenServices(tokenServices());
    }
    
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }
    
    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("shared-secret");
        return converter;
    }
}

客户端配置示例:

java 复制代码
@EnableOAuth2Client
@Configuration
public class OAuth2ClientConfig {
    @Bean
    public OAuth2RestTemplate oauth2RestTemplate(
            OAuth2ClientContext oauth2ClientContext,
            OAuth2ProtectedResourceDetails details) {
        return new OAuth2RestTemplate(details, oauth2ClientContext);
    }
}

安全配置最佳实践

生产环境建议配置:

  • 启用 CSRF 防护(对于有状态的 web 应用)
  • 配置 CORS 策略
  • 强制 HTTPS
  • 设置严格的内容安全策略
  • 使用安全密码编码器:
java 复制代码
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

典型安全配置示例:

java 复制代码
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().ignoringAntMatchers("/api/**")
            .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .antMatchers("/auth/**").permitAll()
                .anyRequest().authenticated();
    }
}
相关推荐
云烟成雨TD20 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
Csvn20 小时前
🌟 LangChain 30 天保姆级教程 · Day 13|OutputParser 进阶!让 AI 输出自动转为结构化对象,并支持自动重试!
python·langchain
Wenweno0o20 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨20 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
swg32132120 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
gelald20 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川20 小时前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java
一轮弯弯的明月21 小时前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
chenjingming66621 小时前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter
殷紫川21 小时前
深入拆解 Java volatile:从内存屏障到无锁编程的实战指南
java