本篇承接上一篇《从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(八)saas平台篇-解决不同租户针定制化开发问题(2) -挂载自定义登陆以及业务端完整代码》,上一篇中具体说明了如何创建租户个性化工程以及详细代码,这里说明代码上如何在认证中心添加tenantId属性
目前登陆返回信息并没有tenantId字段
oauth2 框架认证流程源码分析
详细泳道图
关键代码以及分析
1 客户端请求/oauth/token 进行认证
2 AbstractAuthenticationProcessingFilter 过滤器优先执行调用providerManager 进行校验
3 如果providerManager 的authenticate 没问题,则进入TokenEndpoint 执行postAccessToken 方法
4 TokenEndpoint postAccessToken 内部
4.1 通过 ClientDetailsService获取clientDetails 进行client信息校验 这个是关键点,需要首先数据库添加tenantId字段
4.2 然后将clientDetails 传入ResourceOwnerPasswordTokenGranter 获取OAuth2Authentication
4.3 Granter内部通过OAuth2RequestFactory 获取OAuth2Request 这个是关键点,需要拼装tenantId字段
4.4 DefaultTokenServices 通过OAuth2Request 信息拼装成返回结果返回给客户端 这个是关键点,需要拼装tenantId字段
如何扩展oauth2 框架添加tenantId字段
扩展部分关键点
具体源码
数据库部分添加tenantId 属性
MiniCloudAuthorizationServerConfig添加requestFactory
/**
* @desc: 主要是对endpoints(框架本身的url路径)注入自定义service
* 这里对注入了默认的userDetailsService,authenticationManager,
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST,HttpMethod.DELETE,HttpMethod.PUT)
.tokenStore(tokenStore())
.tokenEnhancer(miniCloudTokenEnhancer)
.userDetailsService(userDetailsService)
.requestFactory(oauth2RequestFactory(ClientDetailServiceImpl))
.authenticationManager(authenticationManager);
}
public OAuth2RequestFactory oauth2RequestFactory(ClientDetailsService clientDetailsService){
MiniCloudOAuth2RequestFactory miniCloudOAuth2RequestFactory = new MiniCloudOAuth2RequestFactory(clientDetailsService);
return miniCloudOAuth2RequestFactory;
}
MiniCloudOAuth2RequestFactory.java
public class MiniCloudOAuth2RequestFactory extends DefaultOAuth2RequestFactory { public MiniCloudOAuth2RequestFactory(ClientDetailsService clientDetailsService) { super(clientDetailsService); } @Override public OAuth2Request createOAuth2Request(ClientDetails client, TokenRequest tokenRequest) { OAuth2Request oAuth2Request = super.createOAuth2Request(client, tokenRequest); oAuth2Request.getExtensions().put("tenantId",(Integer)client.getAdditionalInformation().get("tenantId")); return oAuth2Request; } }
MiniCloudTokenEnhancer.java
/**
* 扩展auth 认证中map 存放token 内容,client 模式不处理
* */
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
if (CLIENT_CREDENTIALS.equals(authentication.getOAuth2Request().getGrantType())) {
return accessToken;
}
final Map<String, Object> additionalInfo = new HashMap<>(8);
MiniCloudUserDetails miniCloudUserDetails = (MiniCloudUserDetails) authentication.getUserAuthentication().getPrincipal();
additionalInfo.put(DETAILS_USER, miniCloudUserDetails);
additionalInfo.put(DETAILS_LICENSE, "made by mini-cloud");
additionalInfo.put(ACTIVE, Boolean.TRUE);
additionalInfo.put("tenantId",authentication.getOAuth2Request().getExtensions().get("tenantId"));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
MiniCloudUserAuthenticationConverter.java
/**
*
* 将check_token 中返回的OAuth2Authentication的getPrincipal 重写为我们自己的miniclouddetail
* */
@Override
@Cacheable(value = "mini_cloud_cache:extractAuthentication:authentication", key = "#responseMap['user_name']", unless = "#result == null")
public Authentication extractAuthentication(Map<String, ?> responseMap) {
if (responseMap.containsKey(USERNAME)) {
Map<String, ?> map = MapUtil.get(responseMap, "user_info", Map.class);
List<Map> authorities = MapUtil.get(map,"miniCloudGrantedAuthorities",List.class);
List<MiniCloudGrantedAuthority> miniCloudGrantedAuthorities = authorities.stream().map(authoritity->{
String method = MapUtil.getStr((Map)authoritity,"method");
String url = MapUtil.getStr((Map)authoritity,"url");
return new MiniCloudGrantedAuthority(method,url);
}).collect(Collectors.toList());
MiniCloudUserDetails miniCloudUserDetails = new MiniCloudUserDetails(MapUtil.getInt(map,"id"),MapUtil.getStr(map,"username"),N_A,miniCloudGrantedAuthorities,MapUtil.getInt(responseMap,"tenantId"));
return new UsernamePasswordAuthenticationToken(miniCloudUserDetails, N_A, miniCloudGrantedAuthorities);
}
return null;
}
重新启动,结果展示,已经有了tenantId字段
本文含有隐藏内容,请 开通VIP 后查看