一、基础版(不推荐)
授权服务器
授权服务器负责对用户进行身份验证,并颁发访问令(Access Token)。
1.添加依赖
xml
<!-- 授权服务器核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- springboot项目推荐-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
<!-- springboot不推荐-->
<!--
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
</dependency>
-->2.核心安全配置
创建一个配置类,用于注册客户端信息、配置授权端点以及用户认证。
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import java.time.Duration;
import java.util.UUID;
@Configuration
@EnableWebSecurity
public class AuthorizationServerConfig {
// 配置HTTP安全过滤器链
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
return http
.securityMatcher("/oauth2/**") // 授权服务器端点
.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.csrf(csrf -> csrf.ignoringRequestMatchers("/oauth2/**")) // 为授权端点禁用CSRF
.formLogin(Customizer.withDefaults()) // 使用表单登录进行用户认证
.build();
}
// 注册客户端信息(示例使用内存存储,生产环境应使用数据库)
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("test-client") // 客户端ID
.clientSecret("{noop}test-secret") // 客户端密钥,{noop}表示明文,生产环境请加密
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/test-client") // 回调地址
.scope("read")
.scope("write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.tokenSettings(TokenSettings.builder()
.accessTokenTimeToLive(Duration.ofHours(1)) // 访问令牌有效期1小时
.refreshTokenTimeToLive(Duration.ofDays(1)) // 刷新令牌有效期1天
.build())
.build();
return new InMemoryRegisteredClientRepository(oidcClient);
}
// 配置授权服务器端点(如token uri, jwk set uri等)
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().build();
}
// 配置用户详情服务(示例使用内存用户,生产环境需对接数据库或LDAP)
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withUsername("user")
.password("{noop}password") // 密码,{noop}表示明文
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
}资源服务器
资源服务器负责验证访问令牌,并保护API资源。
1.添加依赖
xml
<!-- 资源服务器核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>2.核心安全配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class ResourceServerConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll() // 公开接口
.anyRequest().authenticated() // 其他所有接口需要认证
)
// 配置为OAuth2资源服务器,并指定JWT解码方式
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.decoder(jwtDecoder())) // 使用JWT令牌
)
.build();
}
// JWT解码器:配置如何验证令牌(此处假设授权服务器使用对称密钥加密)
@Bean
public JwtDecoder jwtDecoder() {
// 重要:此处的密钥必须与授权服务器用于签发JWT的密钥一致
String jwkSetUri = "http://localhost:9000/oauth2/jwks"; // 授权服务器的JWK Set端点
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
// 如果是本地测试,也可以使用本地公钥:
// return NimbusJwtDecoder.withPublicKey(publicKey).build();
}
}二、进阶版(推荐)
授权服务器
授权服务器负责对用户进行身份验证,并颁发访问令(Access Token)。
1.添加依赖
xml
<!-- 授权服务器核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>资源服务器
application.yml配置:
yml
# 安全配置
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:9000/auth
jwk-set-uri: http://localhost:9000/auth/oauth2/jwks