【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南(二)

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南

【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南(一)https://developer.aliyun.com/article/1470989


实现案例

定义鉴权服务中心服务
建立Dubbo3的服务容器作为鉴权服务实现

Undertow容器处理功能,用于接收对应的Http鉴权请求接口服务,用于处理来资源服务提供者端的Http请求。

数据模型



定义对应的实现鉴权中心鉴权匹配实现类

定义Hutools的数据源DB

在对应的resources下的config文件下建立db.setting文件,之后配置对应的数据源

ini

复制代码

#中括表示一个分组,其下面的所有属性归属于这个分组,在此分组名为ds1,也可以没有分组
[ds1]
#自定义数据源设置文件,这个文件会针对当前分组生效,用于给当前分组配置单独的数据库连接池参数,没有则使用全局的配置
driver = com.mysql.jdbc.Driver
#JDBC url,必须
url = jdbc:mysql://127.0.0.1:3306/dubbo-shopping
#用户名,必须
user = root
#密码,必须,如果密码为空,请填写 pass =
pass = root$
实现查询数据库的Hutool操作

java

复制代码

List<Entity> authData = Db.use(dataSource).query("select * from auth_data");
if(CollectionUtil.isNotEmpty(authData)){
  Entity entity = authData.get(0);
  String ak = entity.getStr("ak");
  String sk = entity.getStr("sk");
}
实现传递过来的数据库的Hutool操作

java

复制代码

@Data
@Slf4j
@NoArgsConstructor
public class AuthService {
    DataSource dataSource = DSFactory.get("ds1");
    /**
     * 匹配ak和sk的值
     * @param appCode
     * @param appKey
     * @param secretKey
     * @return
     */
    public boolean matchSecretKey(String appCode,String appKey,String secretKey){
        log.info("appCode:{} - local-appkey:{} - local-secretKey:{}",appCode,appKey,secretKey);
        if(StringUtils.isEmpty(appKey)){
            return Boolean.FALSE;
        }
        try {
            List<Entity> authData = Db.use(dataSource).query("select * from auth_data where code = ?",appCode);
            if(CollectionUtil.isNotEmpty(authData)){
                Entity entity = authData.get(0);
                String ak = entity.getStr("ak");
                String sk = entity.getStr("sk");
                log.info("remote-appkey:{} - remote-secretKey:{}",ak,sk);
                if(ak.equals(ak)){
                    if(StringUtils.isEmpty(sk)){
                        return Boolean.FALSE;
                    }
                    else if(!SecureUtil.md5(sk).equals(secretKey)){
                        return Boolean.FALSE;
                    }
                }else{
                    return Boolean.FALSE;
                }
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        } catch (SQLException e) {
            log.error("auth is error!",e);
            return Boolean.FALSE;
        }
    }
}

鉴权服务 UndertowContainer

采用Undertow容器服务机制,在之前的章节已经介绍和说明了如何实现对应的dubbo的自定义容器实现,在这里我们使用的是UndertowContainer。如果想要学习可以关注之前的文章章节。

java

复制代码

package com.hyts.assemble.dubbo3.comp.container;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.NumberUtil;
import com.hyts.assemble.dubbo3.comp.auth.AuthService;
import io.undertow.Undertow;
import io.undertow.util.Headers;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.container.Container;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
public class UnderTowContainer implements Container {
    //定义容器端口
    public static final String UNDERTOW_PORT = "dubbo.undertow.port";
    //定义容器contextPath
    public static final String UNDERTOW_DEFAULT_PATH = "dubbo.undertow.path";
    
    private AuthService authService = new AuthService();
    
    //设置HttpHandler回调方法
   final Undertow server = Undertow.builder()
            .addHttpListener(NumberUtil.parseInt(ConfigurationUtils.getProperty(UNDERTOW_PORT)), "localhost")
            .setHandler(exchange -> {
                if(exchange.getRequestPath().equals(ConfigurationUtils.getProperty(UNDERTOW_DEFAULT_PATH))){
                    String appKey = String.valueOf(exchange.getQueryParameters().get("appKey").poll());
                    String secretKey = String.valueOf(exchange.getQueryParameters().get("secretKey").poll());
                    String appCode = String.valueOf(exchange.getQueryParameters().get("appCode").poll());
                    boolean result = authService.matchSecretKey(appCode,appKey,secretKey);
                    exchange.getResponseSender().send(String.valueOf(result));
                }
            }).build();
            
    // 定义启动方法        
    @Override
    public void start() {
        server.start();
    }
   
    // 定义停止方法 
    @Override
    public void stop() {
        server.stop();
    }
}

定义容器的dubbo.properties

ini

复制代码

dubbo.container=spring,jetty,log4j,undertow
dubbo.undertow.path=/auth
dubbo.undertow.port=8081
服务提供端

只需要设置 service.auth 为 true,表示该服务的调用需要鉴权认证通过。param.sign为true表示需要对参数也进行校验,之前的章节的内容我们已经介绍了对应的如何建立校验功能的实现机制控制。

java

复制代码

// (注解方式)
@DubboService(parameters = {"service.auth","true"})
public class AuthServiceImpl implements AuthService {
}

xml

复制代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>
    <dubbo:application name="direct-consumer"/>
    <dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181" check="false"/>
    <dubbo:protocol name="dubbo" port="20880"/>
    <bean id="rpcAuthSampleApi" class="com.dubbo.shopping.commodity.rpc.auth.AuthServiceImpl"/>
    <dubbo:service id="rpcAuthSampleApiHandler" interface="com.dubbo.shopping.commodity.api.AuthService"
                   ref="rpcAuthSampleApi" version="0.0.0" filter="auth">
      <dubbo:parameter key="service.auth" value="true"/>
</dubbo:service>
</beans>
服务提供端-建立服务鉴权过滤器

在之前的章节文章中介绍了对应的META-INF/dubbo下建立org.apache.dubbo.rpc.Filter文件,之后进行auth=com.dubbo.shopping.common.auth.filter.AuthFilter,之后会进行定义我们的authFilter过滤器实现类。

建立dubbo.properties配置信息读取相关的鉴权服务的地址

resources文件下建立dubbo.properties之后添加对应的内容

properties

复制代码

dubbo.auth.url=http://localhost:8081/auth

可以使用对应的配置工具进行获取配置信息。

java

复制代码

ConfigurationUtils.getProperty("dubbo.auth.url")

定义对应的服务提供端-建立服务鉴权过滤器

java

复制代码

@Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        boolean authNeed = Boolean.valueOf(invoker.getUrl().getParameter("service.auth"));
        String ak = invocation.getAttachment("AK");
        String sk = invocation.getAttachment("SK");
        String authUrl = ConfigurationUtils.getProperty("dubbo.auth.url");
        if(authNeed){
            log.info("PROCESS AUTH THE INVOKE!APPKEY {} , SECRETKEY {} : authUrl:{}",ak,sk,authUrl);
            String result = HttpUtil.get(authUrl+"?appCode="+"dubbo-shopping"+"&appKey="+ak+"&secretKey="+sk);
            if(!Boolean.valueOf(result)){
                log.error("NOT AUTH THE INVOKE! APPKEY {} , SECRETKEY {}",ak,sk);
                throw new RpcException("NOT AUTH THE INVOKE!");            }
        }
        log.info("PASS AUTH THE INVOKE!APPKEY {} , SECRETKEY {}",ak,sk);
//        if(paramSign){
//        }
        return invoker.invoke(invocation);
    }
服务消费端

只需要配置好对应的证书等信息即可,之后会自动地在对这些需要认证的接口发起调用前进行签名操作,通过与鉴权服务的交互,用户无需在代码中配置 AK/SK 这些敏感信息,并且在不重启应用的情况下刷新 AK/SK,达到权限动态下发的目的。

该方案目前已经提交给 Dubbo 开源社区,并且完成了基本框架的合并,除了 AK/SK 的鉴权方式之外,通过 SPI 机制支持用户可定制化的鉴权认证以及适配公司内部基础设施的密钥存储。

xml

复制代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>
    <dubbo:application name="direct-consumer"/>
    <dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181" check="false"/>
    <dubbo:provider token="true"/>
    <dubbo:protocol name="dubbo" port="20880"/>
    <dubbo:reference id="authSampleApi" check="false" interface="com.dubbo.shopping.commodity.api.AuthSampleApi" version="*"/>
</beans>
模拟远程调用

java

复制代码

package com.dubbo.shopping.commodity.controller;
import cn.hutool.crypto.SecureUtil;
import com.dubbo.shopping.commodity.api.AnnotationConstants;
import com.dubbo.shopping.commodity.api.AuthSampleApi;
import com.dubbo.shopping.commodity.api.CommodityQueryApi;
import com.dubbo.shopping.commodity.entity.BaseInfo;
import com.dubbo.shopping.commodity.model.CommodityQueryDTO;
import com.dubbo.shopping.model.rpc.RpcRequest;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
 * <p>
 * 商品主题信息 前端控制器
 * </p>
 *
 * @author libo
 * @since 2022-05-08
 */
@RestController
@RequestMapping("/commodity/base-info")
public class BaseInfoController {
    @Autowired
    AuthSampleApi authSampleApi;
    @ApiOperation("权限控制调用")
    @RequestMapping("/auth")
    public ResponseEntity auth(){
        RpcContext.getClientAttachment().setAttachment("AK","dubbo3");
        RpcContext.getClientAttachment().setAttachment("SK", SecureUtil.md5("123456"));
        return ResponseEntity.ok(authSampleApi.executeAuth("test parameter"));
    }
}

既可以实现鉴权服务机制,大家还可以自己进行扩展实现。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
10天前
|
监控 Dubbo Java
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
这篇文章详细介绍了如何将Spring Boot与Dubbo和Zookeeper整合,并通过Dubbo管理界面监控服务注册情况。
21 0
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
|
1月前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
160 17
微服务框架Dubbo环境部署实战
|
1月前
|
缓存 负载均衡 Dubbo
Dubbo技术深度解析及其在Java中的实战应用
Dubbo是一款由阿里巴巴开源的高性能、轻量级的Java分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
58 6
|
2月前
|
JSON Dubbo Java
【Dubbo协议指南】揭秘高性能服务通信,选择最佳协议的终极攻略!
【8月更文挑战第24天】在分布式服务架构中,Apache Dubbo作为一款高性能的Java RPC框架,支持多种通信协议,包括Dubbo协议、HTTP协议及Hessian协议等。Dubbo协议是默认选择,采用NIO异步通讯,适用于高要求的内部服务通信。HTTP协议通用性强,利于跨语言调用;Hessian协议则在数据传输效率上有优势。选择合适协议需综合考虑性能需求、序列化方式、网络环境及安全性等因素。通过合理配置,可实现服务性能最优化及系统可靠性提升。
46 3
|
2月前
|
C# 开发者 Windows
勇敢迈出第一步:手把手教你如何在WPF开源项目中贡献你的第一行代码,从选择项目到提交PR的全过程解析与实战技巧分享
【8月更文挑战第31天】本文指导您如何在Windows Presentation Foundation(WPF)相关的开源项目中贡献代码。无论您是初学者还是有经验的开发者,参与这类项目都能加深对WPF框架的理解并拓展职业履历。文章推荐了一些适合入门的项目如MvvmLight和MahApps.Metro,并详细介绍了从选择项目、设置开发环境到提交代码的全过程。通过具体示例,如添加按钮点击事件处理程序,帮助您迈出第一步。此外,还强调了提交Pull Request时保持专业沟通的重要性。参与开源不仅能提升技能,还能促进社区交流。
39 0
|
5月前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
2月前
|
Dubbo Java 应用服务中间件
💥Spring Cloud Dubbo火爆来袭!微服务通信的终极利器,你知道它有多强大吗?🔥
【8月更文挑战第29天】随着信息技术的发展,微服务架构成为企业应用开发的主流模式,而高效的微服务通信至关重要。Spring Cloud Dubbo通过整合Dubbo与Spring Cloud的优势,提供高性能RPC通信及丰富的生态支持,包括服务注册与发现、负载均衡和容错机制等,简化了服务调用管理并支持多种通信协议,提升了系统的可伸缩性和稳定性,成为微服务通信领域的优选方案。开发者仅需关注业务逻辑,而无需过多关心底层通信细节,使得Spring Cloud Dubbo在未来微服务开发中将更加受到青睐。
77 0
|
2天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
10 2
|
5天前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
1月前
|
Dubbo 应用服务中间件 Apache
Star 4w+,Apache Dubbo 3.3 全新发布,Triple X 领衔,开启微服务通信新时代
在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。
120 8