快速开始
如果你刚开始使用 Spring Security 授权服务器,以下章节将引导你创建第一个应用程序。
系统要求
Spring Security Authorization Server 需要 Java 17 或更高版本的运行时环境。
安装 Spring Security 授权服务器
开始使用 Spring Security Authorization Server 最简单的方式是创建一个基于 Spring Boot 的应用程序。你可以使用 start.spring.io 生成一个基础项目,或者参考 默认授权服务器示例 作为指南。然后添加 Spring Boot 的 Spring Security Authorization Server starter 作为依赖:
- Maven
- Gradle
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server"
有关在 Maven 或 Gradle 中使用 Spring Boot 的更多信息,请参阅 安装 Spring Boot。
或者,你也可以在不使用 Spring Boot 的情况下添加 Spring Security Authorization Server,参考以下示例:
- Maven
- Gradle
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>7.0.2</version>
</dependency>
implementation "org.springframework.security:spring-security-oauth2-authorization-server:7.0.2"
开发您的首个应用程序
要开始使用,你需要将所需的最小组件定义为 @Bean。当使用 spring-boot-starter-oauth2-authorization-server 依赖时,定义以下属性,Spring Boot 将为你提供必要的 @Bean 定义:
server:
port: 9000
logging:
level:
org.springframework.security: trace
spring:
security:
user:
name: user
password: password
oauth2:
authorizationserver:
client:
oidc-client:
registration:
client-id: "oidc-client"
client-secret: "{noop}secret"
client-authentication-methods:
- "client_secret_basic"
authorization-grant-types:
- "authorization_code"
- "refresh_token"
redirect-uris:
- "http://127.0.0.1:8080/login/oauth2/code/oidc-client"
post-logout-redirect-uris:
- "http://127.0.0.1:8080/"
scopes:
- "openid"
- "profile"
require-authorization-consent: true
若需自定义默认的 HttpSecurity 配置,可通过以下示例覆盖 Spring Boot 的自动配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
http
.authorizeHttpRequests((authorize) ->
authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
);
return http.build();
}
}
在入门体验之后,大多数用户会希望自定义默认配置。下一节将演示如何自行提供所有必需的组件。
定义必需组件
若需自定义默认配置(无论是否使用Spring Boot),您可以将所需的最小组件定义为Spring @Configuration中的@Bean。
这些组件可以定义如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean 1
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) -> {
http.securityMatcher(authorizationServer.getEndpointsMatcher());
authorizationServer
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
})
.authorizeHttpRequests((authorize) ->
authorize
.anyRequest().authenticated()
)
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
);
return http.build();
}
@Bean 2
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin(Customizer.withDefaults());
return http.build();
}
@Bean 3
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
@Bean 4
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("oidc-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client")
.postLogoutRedirectUri("http://127.0.0.1:8080/")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
return new InMemoryRegisteredClientRepository(oidcClient);
}
@Bean 5
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() { 6
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean 7
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean 8
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().build();
}
}
这是一个快速入门的最小配置。要了解每个组件的用途,请参阅以下说明:
用于协议端点的 Spring Security 过滤器链。
用于身份验证的 Spring Security 过滤器链。
用于检索要验证的用户的 UserDetailsService 实例。
用于管理客户端的 RegisteredClientRepository 实例。
用于对访问令牌进行签名的
com.nimbusds.jose.jwk.source.JWKSource实例。一个
java.security.KeyPair实例,其密钥在启动时生成,用于创建上述JWKSource。用于解码已签名访问令牌的 JwtDecoder 实例。
用于配置 Spring Security Authorization Server 的 AuthorizationServerSettings 实例。