spring oauth2 authorization server 配置源码解析

2024-01-06 10:35:47 浏览数 (1)

版本

1.2.1

源码

  • OAuth2 授权服务器配置 org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration
代码语言:javascript复制
@Configuration(proxyBeanMethods = false)
public class OAuth2AuthorizationServerConfiguration {
	// 默认授权服务器安全过滤器链
	@Bean
	@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
		applyDefaultSecurity(http);
		return http.build();
	}
	// 应用默认安全配置
	public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
		// 授权服务器配置器
		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
				new OAuth2AuthorizationServerConfigurer();
		// 授权服务器端点请求匹配器
		RequestMatcher endpointsMatcher = authorizationServerConfigurer
				.getEndpointsMatcher();
		http
			// 仅对授权服务器端点请求进行安全配置
			.securityMatcher(endpointsMatcher)
			.authorizeHttpRequests(authorize ->
				authorize.anyRequest().authenticated()
			)
			// 对授权服务器端点关闭csrf保护
			.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
			.apply(authorizationServerConfigurer);
	}
	// 默认JWT解码器
	public static JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
		// 添加支持的算法
		Set<JWSAlgorithm> jwsAlgs = new HashSet<>();
		jwsAlgs.addAll(JWSAlgorithm.Family.RSA);
		jwsAlgs.addAll(JWSAlgorithm.Family.EC);
		jwsAlgs.addAll(JWSAlgorithm.Family.HMAC_SHA);
		// JWT处理器,负责处理签名/加密/明文的jwt
		ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
		JWSKeySelector<SecurityContext> jwsKeySelector =
				new JWSVerificationKeySelector<>(jwsAlgs, jwkSource);
		jwtProcessor.setJWSKeySelector(jwsKeySelector);
		// 覆盖Nimbus默认的JWT声明校验器,不对声明进行校验
		jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
		});
		return new NimbusJwtDecoder(jwtProcessor);
	}
	@Bean
	RegisterMissingBeanPostProcessor registerMissingBeanPostProcessor() {
		RegisterMissingBeanPostProcessor postProcessor = new RegisterMissingBeanPostProcessor();
		postProcessor.addBeanDefinition(AuthorizationServerSettings.class, () -> AuthorizationServerSettings.builder().build());
		return postProcessor;
	}
}
  • OAuth2 授权服务器配置器 org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer
代码语言:javascript复制
public final class OAuth2AuthorizationServerConfigurer
		extends AbstractHttpConfigurer<OAuth2AuthorizationServerConfigurer, HttpSecurity> {
	// 所有授权服务器端点配置器
	private final Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> configurers = createConfigurers();
	// 匹配所有授权服务器端点对应的请求,以及JwkSet端点请求
	private RequestMatcher endpointsMatcher;
	
	...
	
	// 启用OpenID Connect 1.0支持(默认关闭)
	public OAuth2AuthorizationServerConfigurer oidc(Customizer<OidcConfigurer> oidcCustomizer) {
		OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class);
		if (oidcConfigurer == null) {
			addConfigurer(OidcConfigurer.class, new OidcConfigurer(this::postProcess));
			oidcConfigurer = getConfigurer(OidcConfigurer.class);
		}
		oidcCustomizer.customize(oidcConfigurer);
		return this;
	}
	
	...
	// 配置器初始化
	@Override
	public void init(HttpSecurity httpSecurity) {
		// 获取授权服务器设置(各端点url)
		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
		// 校验issuerUri
		validateAuthorizationServerSettings(authorizationServerSettings);
		// 处理OpenID Connect认证请求
		if (isOidcEnabled()) {
			// 如果启用OpenID Connect 1.0
			// 添加 OpenID Connect 会话跟踪能力
			initSessionRegistry(httpSecurity);
			SessionRegistry sessionRegistry = httpSecurity.getSharedObject(SessionRegistry.class);
			// 授权端点设置会话认证策略
			OAuth2AuthorizationEndpointConfigurer authorizationEndpointConfigurer =
					getConfigurer(OAuth2AuthorizationEndpointConfigurer.class);
			authorizationEndpointConfigurer.setSessionAuthenticationStrategy((authentication, request, response) -> {
				// 如果认证请求是使用授权码模式的OAuth2认证请求,且scope包含openid,则将会话注册到会话注册表
				if (authentication instanceof OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication) {
					if (authorizationCodeRequestAuthentication.getScopes().contains(OidcScopes.OPENID)) {
						if (sessionRegistry.getSessionInformation(request.getSession().getId()) == null) {
							sessionRegistry.registerNewSession(
									request.getSession().getId(),
									((Authentication) authorizationCodeRequestAuthentication.getPrincipal()).getPrincipal());
						}
					}
				}
			});
		} else {
			// 如果OpenID Connect 没有启用.
			// 添加认证校验器,拒绝scope包含openid的认证请求
			OAuth2AuthorizationEndpointConfigurer authorizationEndpointConfigurer =
					getConfigurer(OAuth2AuthorizationEndpointConfigurer.class);
			authorizationEndpointConfigurer.addAuthorizationCodeRequestAuthenticationValidator((authenticationContext) -> {
				OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
						authenticationContext.getAuthentication();
				if (authorizationCodeRequestAuthentication.getScopes().contains(OidcScopes.OPENID)) {
					OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_SCOPE,
							"OpenID Connect 1.0 authentication requests are restricted.",
							"https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1");
					throw new OAuth2AuthorizationCodeRequestAuthenticationException(
							error, authorizationCodeRequestAuthentication);
				}
			});
		}
		// 构造授权端点请求匹配器
		List<RequestMatcher> requestMatchers = new ArrayList<>();
		// 添加每个端点对应的匹配规则
		this.configurers.values().forEach(configurer -> {
			configurer.init(httpSecurity);
			requestMatchers.add(configurer.getRequestMatcher());
		});
		// 添加JwkSet端点请求匹配规则
		requestMatchers.add(new AntPathRequestMatcher(
				authorizationServerSettings.getJwkSetEndpoint(), HttpMethod.GET.name()));
		this.endpointsMatcher = new OrRequestMatcher(requestMatchers);
		// 当令牌获取/内省/撤回/设备认证端点发生访问拒绝异常或者认证异常时返回401未授权响应
		ExceptionHandlingConfigurer<HttpSecurity> exceptionHandling = httpSecurity.getConfigurer(ExceptionHandlingConfigurer.class);
		if (exceptionHandling != null) {
			exceptionHandling.defaultAuthenticationEntryPointFor(
					new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
					new OrRequestMatcher(
							getRequestMatcher(OAuth2TokenEndpointConfigurer.class),
							getRequestMatcher(OAuth2TokenIntrospectionEndpointConfigurer.class),
							getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class),
							getRequestMatcher(OAuth2DeviceAuthorizationEndpointConfigurer.class))
			);
		}
	}
	// 执行安全配置
	@Override
	public void configure(HttpSecurity httpSecurity) {
		// 应用各端点配置器
		this.configurers.values().forEach(configurer -> configurer.configure(httpSecurity));
		// 获取授权服务器设置
		AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
		// 添加授权服务器上下文过滤器,负责将上下文设置到AuthorizationServerContextHolder
		AuthorizationServerContextFilter authorizationServerContextFilter = new AuthorizationServerContextFilter(authorizationServerSettings);
		httpSecurity.addFilterAfter(postProcess(authorizationServerContextFilter), SecurityContextHolderFilter.class);
		// 添加JwkSet端点过滤器
		JWKSource<com.nimbusds.jose.proc.SecurityContext> jwkSource = OAuth2ConfigurerUtils.getJwkSource(httpSecurity);
		if (jwkSource != null) {
			NimbusJwkSetEndpointFilter jwkSetEndpointFilter = new NimbusJwkSetEndpointFilter(
					jwkSource, authorizationServerSettings.getJwkSetEndpoint());
			httpSecurity.addFilterBefore(postProcess(jwkSetEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
		}
	}
	// 创建OAuth2服务器端点配置器
	private Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> createConfigurers() {
		Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> configurers = new LinkedHashMap<>();
		// 客户端认证
		configurers.put(OAuth2ClientAuthenticationConfigurer.class, new OAuth2ClientAuthenticationConfigurer(this::postProcess));
		// 授权服务器元数据端点
		configurers.put(OAuth2AuthorizationServerMetadataEndpointConfigurer.class, new OAuth2AuthorizationServerMetadataEndpointConfigurer(this::postProcess));
		// 授权端点
		configurers.put(OAuth2AuthorizationEndpointConfigurer.class, new OAuth2AuthorizationEndpointConfigurer(this::postProcess));
		// 令牌获取端点
		configurers.put(OAuth2TokenEndpointConfigurer.class, new OAuth2TokenEndpointConfigurer(this::postProcess));
		// 令牌内省端点
		configurers.put(OAuth2TokenIntrospectionEndpointConfigurer.class, new OAuth2TokenIntrospectionEndpointConfigurer(this::postProcess));
		// 令牌撤回端点
		configurers.put(OAuth2TokenRevocationEndpointConfigurer.class, new OAuth2TokenRevocationEndpointConfigurer(this::postProcess));
		// 设备授权端点
		configurers.put(OAuth2DeviceAuthorizationEndpointConfigurer.class, new OAuth2DeviceAuthorizationEndpointConfigurer(this::postProcess));
		// 设备校验端点
		configurers.put(OAuth2DeviceVerificationEndpointConfigurer.class, new OAuth2DeviceVerificationEndpointConfigurer(this::postProcess));
		return configurers;
	}
}

0 人点赞