Spring Boot 实现单点登录

以下是基于 Spring Boot 实现单点登录(SSO)的代码示例,结合 OAuth2.0JWT 方案,适用于微服务架构或独立系统集成。代码分为 认证服务器(Auth Server)资源服务器(Resource Server)客户端配置 三部分,并附详细说明。


1. 认证服务器(Auth Server)

负责用户认证和令牌颁发,使用 Spring Security OAuth2 和 JWT。

依赖配置(pom.xml)

<dependencies>
    <!-- Spring Security OAuth2 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
    </dependency>
    <!-- JWT 支持 -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
    <!-- Redis 用于令牌存储 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

认证服务器配置类

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("client-app")  // 客户端ID
            .secret("{noop}secret")   // 客户端密钥(未加密)
            .authorizedGrantTypes("authorization_code", "refresh_token", "password")
            .scopes("read", "write")  // 权限范围
            .redirectUris(" http://localhost:8081/login/oauth2/code/client-app ");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
            .authenticationManager(authenticationManager)
            .tokenStore(tokenStore())
            .accessTokenConverter(jwtAccessTokenConverter());
    }

    @Bean
    public TokenStore tokenStore() {
        return new RedisTokenStore(redisTemplate.getConnectionFactory());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("your-secret-key");  // JWT签名密钥
        return converter;
    }
}

Spring Security 配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/oauth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

2. 资源服务器(Resource Server)

保护受控资源,验证令牌有效性。

依赖配置(pom.xml)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

资源服务器配置类

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .antMatchers("/api/**").authenticated();
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withSecretKey(
            new SecretKeySpec("your-secret-key".getBytes(), "HMACSHA256")
        ).build();
    }
}

受保护资源接口

@RestController
@RequestMapping("/api")
public class ResourceController {
    @GetMapping("/user")
    public String getUser(Principal principal) {
        return "Hello, " + principal.getName();
    }
}

3. 客户端应用配置

使用 OAuth2 客户端库接入认证服务器。

application.yml 配置

spring:
  security:
    oauth2:
      client:
        registration:
          sso:
            client-id: client-app
            client-secret: secret
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            scope: read,write
        provider:
          sso:
            issuer-uri: http://localhost:8080   # 认证服务器地址

Spring Security 配置

@Configuration
@EnableWebSecurity
public class ClientSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login();
    }
}

4. 运行与测试

  1. 启动服务:依次启动认证服务器(8080 端口)、资源服务器(8081 端口)和客户端应用(8082 端口)。

  2. 访问流程

    • 用户访问客户端应用的受保护资源(如 http://localhost:8082/api/user)。

    • 客户端重定向到认证服务器登录页面。

    • 登录成功后返回令牌,客户端通过令牌访问资源服务器。


关键点说明

  • OAuth2 授权模式:支持 authorization_code(推荐)、password 等模式。

  • JWT 令牌:自包含、无状态,适合微服务场景。

  • Redis 存储:用于管理令牌状态(如吊销)。

  • 跨域问题:需配置 CORS 过滤器。

完整代码可参考 Spring Security OAuth2 官方文档 或上述示例。


Spring Boot 实现单点登录
https://uniomo.com/archives/spring-boot-shi-xian-dan-dian-deng-lu
作者
雨落秋垣
发布于
2025年09月06日
许可协议