Skip to content

Session、JWT、OAuth2

Session 模式

Session 模式的重点不是登录接口,而是认证成功后服务端如何保存状态。

java
@Bean
SecurityFilterChain webChain(HttpSecurity http) throws Exception {
    return http
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED))
            .formLogin(Customizer.withDefaults())
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .build();
}

特点:

  • 服务端保存会话。
  • 浏览器天然适配。
  • 强制下线、会话并发控制更直接。

JWT 模式

JWT 模式把登录态变成签名后的声明。

java
@Service
class JwtService {

    String generate(String username, List<String> authorities) {
        return username + ":" + String.join(",", authorities);
    }
}
java
@Component
class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String authorization = request.getHeader("Authorization");
        if (authorization != null && authorization.startsWith("Bearer ")) {
            Authentication authentication = new UsernamePasswordAuthenticationToken(
                    "jwtUser", null, List.of(new SimpleGrantedAuthority("ROLE_USER")));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }
}
java
@Bean
SecurityFilterChain jwtChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception {
    return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/api/auth/**").permitAll()
                    .anyRequest().authenticated())
            .build();
}

OAuth2 登录

OAuth2 登录的核心不是“多一个登录方式”,而是把第三方授权流程挂进安全过滤器链。

java
@Bean
SecurityFilterChain oauth2Chain(HttpSecurity http) throws Exception {
    return http
            .oauth2Login(Customizer.withDefaults())
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/", "/login/**").permitAll()
                    .anyRequest().authenticated())
            .build();
}
yaml
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: your-client-id
            client-secret: your-client-secret

资源服务器 JWT

如果系统本身只是资源服务,不负责颁发令牌,直接用资源服务器配置更自然。

java
@Bean
SecurityFilterChain resourceServerChain(HttpSecurity http) throws Exception {
    return http
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .build();
}

选型

  • Session:后台管理、传统页面站点。
  • JWT:前后端分离、网关后 API。
  • OAuth2:第三方身份集成、统一认证平台。