|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Security 7.0.4! |
快速开始
如果你刚刚开始使用 Spring Security 授权服务器,以下部分将引导你创建你的第一个应用程序。
安装 Spring Security 授权服务器
开始使用 Spring Security 授权服务器最简单的方法是创建一个基于 Spring Boot 的应用程序。 你可以使用 start.spring.io 生成一个基础项目,或者参考 默认的授权服务器示例。 然后将 Spring Boot 提供的 Spring Security 授权服务器 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 授权服务器:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>7.1.0-SNAPSHOT</version>
</dependency>
implementation "org.springframework.security:spring-security-oauth2-authorization-server:7.1.0-SNAPSHOT"
开发您的第一个应用程序
要开始使用,您需要将所需的最少组件定义为 @Bean。当使用 spring-boot-starter-oauth2-authorization-server 依赖项时,请定义以下属性,Spring Boot 将为您自动提供必要的 @Bean 定义:
application.yml
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 的自动配置:
SecurityConfig.java
@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();
}
}
| 除了入门体验之外,大多数用户都希望自定义默认配置。下一节演示如何自行提供所有必要的 Bean。 |
定义所需组件
如果你想自定义默认配置(无论是否使用 Spring Boot),可以在 Spring 的 @Bean 中将所需的最少组件定义为 @Configuration。
这些组件可以按如下方式定义:
SecurityConfig.java
@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();
}
}
这是一个用于快速入门的最小化配置。要了解每个组件的用途,请参见以下说明:
| 1 | 用于协议端点的 Spring Security 过滤器链。 |
| 2 | 用于身份验证的 Spring Security 过滤器链。 |
| 3 | 用于检索用户进行身份验证的UserDetailsService实例。 |
| 4 | 用于管理客户端的 RegisteredClientRepository 实例。 |
| 5 | 用于对访问Tokens进行签名的 com.nimbusds.jose.jwk.source.JWKSource 实例。 |
| 6 | 一个在启动时生成密钥的 java.security.KeyPair 实例,用于创建上面的 JWKSource。 |
| 7 | 用于解码签名访问Tokens的 JwtDecoder 实例。 |
| 8 | 用于配置 Spring Security 授权服务器的 AuthorizationServerSettings 实例。 |