入門

如果您剛剛開始使用 Spring Security 授權伺服器,以下各節將引導您建立第一個應用程式。

系統要求

Spring Security 授權伺服器需要 Java 17 或更高版本的執行時環境。

安裝 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"
有關如何將 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</version>
</dependency>
implementation "org.springframework.security:spring-security-oauth2-authorization-server:7.0.0"

開發您的第一個應用程式

首先,您需要定義為 @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 @Configuration 中將最低所需元件定義為 @Bean

這些元件可以定義如下

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 一個用於簽署訪問令牌的 com.nimbusds.jose.jwk.source.JWKSource 例項。
6 一個在啟動時生成金鑰的 java.security.KeyPair 例項,用於建立上述 JWKSource
7 一個用於解碼已簽署訪問令牌的 JwtDecoder 例項。
8 一個用於配置 Spring Security 授權伺服器的 AuthorizationServerSettings 例項。
© . This site is unofficial and not affiliated with VMware.