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

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 从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月前
|
监控 Java 持续交付
后端开发中的微服务架构实践与挑战####
在当今快速迭代的软件开发领域,微服务架构以其灵活性和可扩展性成为众多企业的首选。本文探讨了微服务架构的核心概念、实施策略及面临的主要挑战,旨在为后端开发者提供一个全面的指南。通过分析真实案例,揭示微服务在提升系统敏捷性的同时,如何有效应对分布式系统的复杂性问题。 ####
|
2月前
|
消息中间件 API 持续交付
后端开发中的微服务架构实践####
【10月更文挑战第21天】 本文深入探讨了微服务架构在后端开发中的应用,从基本概念出发,详细阐述了微服务的核心优势、设计原则及关键技术。通过实际案例分析,揭示了微服务如何助力企业应对复杂业务需求,提升系统的可扩展性、灵活性与可靠性。同时,也指出了实施微服务过程中可能面临的挑战,并提供了相应的解决方案和最佳实践。 ####
35 3
|
1月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
167 69
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
15天前
|
运维 监控 Java
为何内存不够用?微服务改造启动多个Spring Boot的陷阱与解决方案
本文记录并复盘了生产环境中Spring Boot应用内存占用过高的问题及解决过程。系统上线初期运行正常,但随着业务量上升,多个Spring Boot应用共占用了64G内存中的大部分,导致应用假死。通过jps和jmap工具排查发现,原因是运维人员未设置JVM参数,导致默认配置下每个应用占用近12G内存。最终通过调整JVM参数、优化堆内存大小等措施解决了问题。建议在生产环境中合理设置JVM参数,避免资源浪费和性能问题。
42 3
|
2月前
|
消息中间件 监控 持续交付
后端开发中的微服务架构设计与实践####
在当今快速发展的软件开发领域,微服务架构已成为构建高效、可扩展和易于维护应用的关键策略。本文将深入探讨微服务架构的核心概念、设计原则与实战技巧,通过实例解析如何在后端开发中有效实施微服务,以应对复杂业务需求和技术挑战。我们将从微服务的拆分策略、通信机制、数据管理到持续集成/持续部署(CI/CD)流程,全面剖析其背后的技术细节与最佳实践,为读者提供一份详尽的微服务架构设计与实践指南。 ####
|
1月前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
1月前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
41 1
|
1月前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
46 1
|
1月前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。
|
2月前
|
消息中间件 运维 开发者
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在后端开发中的应用,从其核心概念、设计原则到实际部署过程中面临的挑战进行了全面剖析。不同于传统的单体应用,微服务通过将复杂系统拆解为一系列小型、独立的服务,提高了系统的灵活性和可维护性。然而,这种架构的转变也伴随着服务间通信、数据一致性、部署复杂性等新问题。本文旨在为开发者提供一套应对这些挑战的策略,同时分享一些成功案例,以期促进微服务架构的有效实施。 ####