从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(八)saas平台篇-解决不同租户针定制化开发问题(3) -oauth2 登陆源码分析以及扩展添加tenantId属性

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介: 从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(八)saas平台篇-解决不同租户针定制化开发问题(3) -oauth2 登陆源码分析以及扩展添加tenantId属性

本篇承接上一篇《从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(八)saas平台篇-解决不同租户针定制化开发问题(2) -挂载自定义登陆以及业务端完整代码》,上一篇中具体说明了如何创建租户个性化工程以及详细代码,这里说明代码上如何在认证中心添加tenantId属性

1.png

目前登陆返回信息并没有tenantId字段


oauth2 框架认证流程源码分析


详细泳道图


1.png

关键代码以及分析


1 客户端请求/oauth/token 进行认证


2 AbstractAuthenticationProcessingFilter 过滤器优先执行调用providerManager 进行校验


1.png

1.png

1.png

3 如果providerManager 的authenticate 没问题,则进入TokenEndpoint 执行postAccessToken 方法


4 TokenEndpoint postAccessToken 内部


4.1 通过 ClientDetailsService获取clientDetails  进行client信息校验 这个是关键点,需要首先数据库添加tenantId字段


image.png

4.2 然后将clientDetails 传入ResourceOwnerPasswordTokenGranter 获取OAuth2Authentication


1.png

4.3 Granter内部通过OAuth2RequestFactory 获取OAuth2Request 这个是关键点,需要拼装tenantId字段


1.png

4.4 DefaultTokenServices 通过OAuth2Request 信息拼装成返回结果返回给客户端 这个是关键点,需要拼装tenantId字段


1.png

1.png

1.png

如何扩展oauth2 框架添加tenantId字段


扩展部分关键点


image.png

具体源码


数据库部分添加tenantId 属性

1.png

MiniCloudAuthorizationServerConfig添加requestFactory

1.png

    /**
     * @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字段


1.png

1.png

相关文章
|
2月前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
182 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
21天前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
42 6
|
1月前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
94 16
|
8天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
1月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
2月前
|
Java 关系型数据库 Nacos
微服务SpringCloud链路追踪之Micrometer+Zipkin
SpringCloud+Openfeign远程调用,并用Mircrometer+Zipkin进行链路追踪
315 20
|
1月前
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
73 1
|
3月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
214 6
|
3月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
85 1