このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Security 6.5.6 を使用してください! |
入門
Spring Security 認可サーバーの使用を初めて行う場合は、次のセクションで最初のアプリケーションの作成手順を説明します。
Spring Security 認証サーバーのインストール
Spring Security 認可サーバーを使い始める最も簡単なメソッドは、Spring Boot ベースのアプリケーションを作成することです。start.spring.io を使って基本的なプロジェクトを生成するか、デフォルトの認可サーバーサンプル [GitHub] (英語) をガイドとして使用できます。次に、Spring Boot の Spring Security 認可サーバー用スターターを依存関係として追加します。
| Spring Boot を Maven または Gradle と共に使用する方法の詳細については、Spring Boot のインストールを参照してください。 |
あるいは、次の例を使用して、Spring Boot なしで Spring Security 認証サーバーを追加することもできます。
Maven
Gradle
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>7.0.0-RC1</version>
</dependency>implementation "org.springframework.security:spring-security-oauth2-authorization-server:7.0.0-RC1"初めてのアプリケーションの開発
開始するには、@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| ほとんどのユーザーは、「入門」エクスペリエンスを超えて、デフォルト構成をカスタマイズしたいと思うでしょう。次のセクションでは、必要な Bean をすべて自分で提供する方法を示します。 |
必要なコンポーネントの定義
デフォルト構成をカスタマイズする場合は (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();
}
}これは、すぐに開始するための最小限の構成です。各コンポーネントの用途を理解するには、次の説明を参照してください。
| 1 | プロトコルエンドポイント用の Spring Security フィルターチェーン。 |
| 2 | 認証用の Spring Security フィルターチェーン。 |
| 3 | 認証するユーザーを取得するための UserDetailsService (Javadoc) のインスタンス。 |
| 4 | クライアントを管理するための RegisteredClientRepository のインスタンス。 |
| 5 | アクセストークンに署名するための com.nimbusds.jose.jwk.source.JWKSource のインスタンス。 |
| 6 | 上記の JWKSource を作成するために使用される、起動時に生成されたキーを持つ java.security.KeyPair のインスタンス。 |
| 7 | 署名付きアクセストークンをデコードするための JwtDecoder (Javadoc) のインスタンス。 |
| 8 | Spring Security 認可サーバーを構成するための AuthorizationServerSettings のインスタンス。 |