入门

如果您刚刚开始使用 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.