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

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 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

相关文章
|
4天前
|
运维 监控 API
后端开发中的微服务架构:优势与挑战
【8月更文挑战第16天】在软件开发的世界中,微服务架构已经成为一种流行和强大的设计模式。它通过将应用程序分解为一组小型、独立的服务来促进敏捷开发和快速迭代。本文旨在深入探讨微服务架构的核心优势以及实施过程中可能遇到的挑战,帮助读者更好地理解这一现代软件设计方法。
|
1天前
|
消息中间件 NoSQL 持续交付
构建高效微服务架构:后端开发的新范式
【7月更文挑战第50天】在数字化转型的浪潮中,微服务架构已成为推动企业敏捷开发和维护的关键。本文深入探讨了如何构建一个高效的微服务架构,包括选择合适的技术栈、确保服务的可伸缩性与弹性、以及实现持续集成和持续部署(CI/CD)。通过分析具体案例,文章揭示了后端开发者如何在不断变化的技术环境中保持竞争力,并提出了优化策略以提升系统整体性能和可靠性。
|
1天前
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
7 1
|
1天前
|
Java 微服务 Spring
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
文章介绍了如何利用Spring Cloud Alibaba快速构建大型电商系统的分布式微服务,包括服务限流降级等主要功能的实现,并通过注解和配置简化了Spring Cloud应用的接入和搭建过程。
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
|
4天前
|
运维 Java Nacos
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
Spring Cloud应用框架:Nacos作为服务注册中心和配置中心
|
6天前
|
监控 Java 测试技术
代码更新不停机:Spring Boot应用实现零停机更新的新质生产力
【8月更文挑战第14天】在快节奏的软件开发与运维环境中,应用的持续部署与更新成为了提升竞争力的关键。传统的停机更新方式不仅影响用户体验,还可能造成业务中断和数据丢失。因此,实现Spring Boot应用的零停机更新成为了现代软件开发团队追求的目标。本文将深入探讨如何通过一系列技术和策略,在不影响服务可用性的前提下,实现Spring Boot应用的平滑升级。
20 2
|
6天前
|
开发框架 Dubbo 应用服务中间件
微服务开发框架-----Apache Dubbo
这篇文章介绍了Apache Dubbo微服务开发框架,它提供RPC通信和微服务治理能力,支持服务发现、负载均衡和流量治理等功能,并强调了Dubbo在微服务规模化实践和企业级治理方面的优势。
微服务开发框架-----Apache Dubbo
|
1天前
|
Kubernetes 数据库 开发者
后端开发中的微服务架构实践
【8月更文挑战第19天】本文将深入探讨微服务架构在后端开发中的应用,包括其设计原则、挑战与解决方案。文章旨在为读者提供一种现代后端开发的新视角,帮助开发者更好地理解并应用微服务架构以提升系统的可维护性、可扩展性和敏捷性。
|
1天前
|
运维 API 持续交付
后端开发中的微服务架构实践
【8月更文挑战第19天】在现代软件工程中,微服务架构作为一种灵活、可扩展的后端解决方案,正逐渐取代传统的单体应用。本文将深入探讨微服务的核心概念、设计原则和实际应用策略,旨在为读者提供一套完整的微服务架构实施指南。
6 0
|
3天前
|
运维 监控 数据库
后端开发中的微服务架构:优势与挑战
【8月更文挑战第17天】在软件开发领域,微服务架构已成为构建复杂系统的重要方法。它通过将应用程序拆分成小型、独立的服务,提高了系统的可维护性、可扩展性和灵活性。然而,这种架构风格也带来了新的挑战,如服务间的通信、数据一致性和运维复杂性等。本文将深入探讨微服务架构的优势和面临的主要问题,并分析如何在实际应用中平衡这些利弊。