1,首先引入依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
2,编写代码
package org.jeckxu.magical.core.dubbo.interceptor.props;
import com.google.common.collect.Maps;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @author jeckxu
*/
@Data
@Component(DubboAuthProperties.BEAN_NAME)
@ConfigurationProperties(DubboAuthProperties.PREFIX)
public class DubboAuthProperties implements Serializable {
public static final String PREFIX = "magical.dubbo.auth";
public static final String BEAN_NAME = "dubboAuthProperties";
/**
* 是否开启Dubbo 服务鉴权:默认为:false
*/
private Boolean enabled = Boolean.FALSE;
private Map<String, List<String>> appIdAllowedOfPath = Maps.newHashMap();
}
package org.jeckxu.magical.core.dubbo.interceptor.constants;
/**
* @author jeckxu
*/
public interface DubboConstants {
String PROVIDER = "provider";
String CONSUMER = "consumer";
String TRACE_ID = "traceId";
}
package org.jeckxu.magical.core.dubbo.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.jeckxu.magical.core.dubbo.interceptor.constants.DubboConstants;
import org.jeckxu.magical.core.tool.api.R;
import org.jeckxu.magical.core.tool.utils.StringUtil;
import org.springframework.boot.system.SystemProperties;
/**
* @author jeckxu
*/
@Slf4j
@Activate(group = {DubboConstants.CONSUMER})
public class DubboConsumerAuthFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String appId = SystemProperties.get("spring.application.name");
String currentPath = invoker.getUrl().getPath().concat("." + invocation.getMethodName());
if (StringUtil.isNotBlank(appId)) {
RpcContext.getContext().setAttachment("app_id", appId);
return invoker.invoke(invocation);
} else {
log.error(" [DUBBO] Consumer 获取服务名称失败,Dubbo Consumer 停止调用!Path:".concat(currentPath));
return AsyncRpcResult.newDefaultAsyncResult(
R.fail("Consumer 获取服务名称失败,Dubbo Consumer 停止调用!Path:" + currentPath), invocation);
}
}
}
package org.jeckxu.magical.core.dubbo.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionFactory;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.*;
import org.jeckxu.magical.core.dubbo.interceptor.constants.DubboConstants;
import org.jeckxu.magical.core.dubbo.interceptor.props.DubboAuthProperties;
import org.jeckxu.magical.core.tool.api.R;
import java.util.List;
/**
* @author jeckxu
*/
@Slf4j
@Activate(group = {DubboConstants.PROVIDER})
public class DubboProviderAuthFilter implements Filter {
ExtensionFactory objectFactory =
ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension();
private final DubboAuthProperties dubboAuthProperties
= objectFactory.getExtension(DubboAuthProperties.class, DubboAuthProperties.BEAN_NAME);
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (dubboAuthProperties.getEnabled()) {
String appId = RpcContext.getContext().getAttachment("app_id");
String currentPath = invoker.getUrl().getPath().concat("." + invocation.getMethodName());
List<String> currentPathAllowedAppIds = dubboAuthProperties.getAppIdAllowedOfPath().get(currentPath);
if (null == currentPathAllowedAppIds) {
log.warn(" [DUBBO] Provider 该接口无权限配置,请留意!Path:{},AppId:{}", currentPath, appId);
return invoker.invoke(invocation);
}
if (currentPathAllowedAppIds.contains(appId)) {
return invoker.invoke(invocation);
} else {
log.error(" [DUBBO] Provider 接口鉴权失败,无法提供服务!Path:{},AppId:{}", currentPath, appId);
return AsyncRpcResult.newDefaultAsyncResult(R.fail("Provider 接口鉴权失败,无法提供服务!Path:"
+ currentPath + ",AppId:" + appId), invocation);
}
} else {
return invoker.invoke(invocation);
}
}
}
以上就是基于Filter 实现的Dubbo服务权限控制代码了,现在我们在Dubbo 服务的Provider端编写配置文件。
magical:
dubbo:
auth:
enabled: true
app-id-allowed-of-path:
org.jeckxu.magical.system.user.rpc.AuthRpc.adminLogin:
- aaaaa
现在,只有AppId 为 aaaaa 的 Dubbo Consumer 端才可以调用 org.jeckxu.magical.system.user.rpc.AuthRpc.adminLogin 服务。
配合Spring Cloud Alibaba Nacos组件可以实现动态配置。