前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring seciruty oauth2 client配置

spring seciruty oauth2 client配置

作者头像
路过君
发布2024-01-06 10:36:22
1920
发布2024-01-06 10:36:22
举报

版本

spring boot 3.2.1 spring seciruty 6.2.1

配置

  • OAuth2 客户端配置文件 application.yml
代码语言:javascript
复制
spring:
  security:
    oauth2:
      client:
        registration:
          auth-client:
            provider: auth-server # 授权服务器(如果不配置,则provider需要使用auth-client作为key)
            client-id: oidc-client # 客户端ID
            client-name: 客户端 # 客户端名称
            client-secret: secret # 客户端密码
            authorization-grant-type: authorization_code # 授权方式
            redirect-uri: http://localhost:8080/login/oauth2/code/auth-server # 授权码模式完成授权后跳转的地址(最后一节为provider.key)
            scope: openid,profile # 请求的scope
        provider:
          auth-server:
            # issuer-uri: http://localhost:8081 自动从授权服务器获取元数据
            authorization-uri: http://localhost:8081/oauth2/authorize # 授权端点
            token-uri: http://localhost:8081/oauth2/token # 令牌获取端点
            user-info-uri: http://localhost:8081/userinfo # 用户信息端点
            jwk-set-uri: http://localhost:8081/oauth2/jwks # JWS端点
            user-name-attribute: sub # 用户名属性(OpenID Connect 默认使用sub声明字段保存用户名,如果自定义用户信息结构则需要改为对应声明字段名)

注: 如果授权服务器开放了元数据端点,可通过配置issuer-uri,自动通过授权服务器获取元数据,无需配置provider中的各端点uri

在这里插入图片描述
在这里插入图片描述

源码

  • OAuth2客户端属性映射 org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper
代码语言:javascript
复制
public final class OAuth2ClientPropertiesMapper {
	private static ClientRegistration getClientRegistration(String registrationId,
			OAuth2ClientProperties.Registration properties, Map<String, Provider> providers) {
		// 尝试通过issuer配置获取客户端注册信息(授权服务器元数据)
		Builder builder = getBuilderFromIssuerIfPossible(registrationId, properties.getProvider(), providers);
		if (builder == null) {
			// 如果获取失败则根据配置构造
			builder = getBuilder(registrationId, properties.getProvider(), providers);
		}
		// 使用配置覆盖构造器默认值(没有配置或空值则不应用)
		PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
		map.from(properties::getClientId).to(builder::clientId);
		map.from(properties::getClientSecret).to(builder::clientSecret);
		map.from(properties::getClientAuthenticationMethod)
			.as(ClientAuthenticationMethod::new)
			.to(builder::clientAuthenticationMethod);
		map.from(properties::getAuthorizationGrantType)
			.as(AuthorizationGrantType::new)
			.to(builder::authorizationGrantType);
		map.from(properties::getRedirectUri).to(builder::redirectUri);
		map.from(properties::getScope).as(StringUtils::toStringArray).to(builder::scope);
		map.from(properties::getClientName).to(builder::clientName);
		return builder.build();
	}
	// 尝试通过issuer获取客户端注册信息构造器
	private static Builder getBuilderFromIssuerIfPossible(String registrationId, String configuredProviderId,
			Map<String, Provider> providers) {
		// 如果客户端注册配置中没有配置providerId,则使用客户端注册ID作为providerId
		String providerId = (configuredProviderId != null) ? configuredProviderId : registrationId;
		// provider配置了issuerUri,则通过issuer查询客户端注册信息
		if (providers.containsKey(providerId)) {
			Provider provider = providers.get(providerId);
			String issuer = provider.getIssuerUri();
			if (issuer != null) {
				Builder builder = ClientRegistrations.fromIssuerLocation(issuer).registrationId(registrationId);
				return getBuilder(builder, provider);
			}
		}
		return null;
	}
	// 获取客户端注册信息构造器
	private static Builder getBuilder(String registrationId, String configuredProviderId,
			Map<String, Provider> providers) {
		// 如果客户端注册配置中没有配置providerId,则使用客户端注册ID作为providerId
		String providerId = (configuredProviderId != null) ? configuredProviderId : registrationId;
		// 获取通用provider(GOOGLE,GITHUB,FACEBOOK,OKTA)
		CommonOAuth2Provider provider = getCommonProvider(providerId);
		if (provider == null && !providers.containsKey(providerId)) {
			throw new IllegalStateException(getErrorMessage(configuredProviderId, registrationId));
		}
		// 如果获取到通用provider, 则使用通用provider创建builder,否则使用客户端注册信息创建builder
		Builder builder = (provider != null) ? provider.getBuilder(registrationId)
				: ClientRegistration.withRegistrationId(registrationId);
		// 如果配置信息中包含了provider配置,则将配置信息应用到builder中
		if (providers.containsKey(providerId)) {
			return getBuilder(builder, providers.get(providerId));
		}
		return builder;
	}
}
  • 客户端注册构造器工具类 org.springframework.security.oauth2.client.registration.ClientRegistrations
代码语言:javascript
复制
public final class ClientRegistrations {
	...
	// 从issuer获取客户端注册配置信息
	public static ClientRegistration.Builder fromIssuerLocation(String issuer) {
		Assert.hasText(issuer, "issuer cannot be empty");
		URI uri = URI.create(issuer);
		// 可支持从 OpenID Connect, OAuth授权服务器获取元数据
		return getBuilder(issuer, oidc(uri), oidcRfc8414(uri), oauth(uri));
	}
	...
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 版本
  • 配置
  • 源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档