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組件可以實現動態配置。