-
Notifications
You must be signed in to change notification settings - Fork 20
12. 使用HttpServerFilter重构边缘服务统一认证和日志扩展(0.0.9)
zhengyangyong edited this page Jul 16, 2018
·
1 revision
ServiceComb Java Chassis针对Http请求提供了一套内置的Filter机制:
接口名 | 描述 |
---|---|
org.apache.servicecomb.common.rest.filter.HttpServerFilter | Producer端接受Http请求扩展 |
org.apache.servicecomb.common.rest.filter.HttpClientFilter | Consumer端发起Http请求扩展 |
因此在边缘服务中的EdgeFilter可以使用这套内置机制中的org.apache.servicecomb.common.rest.filter.HttpServerFilter
替换,实现起来更为简单。
提示:内置的Filter机制是全异步的,因此不需要做异步化处理。
public class AuthenticationFilter implements HttpServerFilter {
private final RestTemplate template = RestTemplateBuilder.create();
private static final String USER_SERVICE_NAME = "user-service";
public static final String EDGE_AUTHENTICATION_NAME = "edge-authentication-name";
private static final Set<String> NOT_REQUIRED_VERIFICATION_USER_SERVICE_METHODS = new HashSet<>(
Arrays.asList("login", "logon", "validate"));
@Override
public int getOrder() {
return 0;
}
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx httpServletRequestEx) {
if (isInvocationNeedValidate(invocation.getMicroserviceName(), invocation.getOperationName())) {
String token = httpServletRequestEx.getHeader(AUTHORIZATION);
if (StringUtils.isNotEmpty(token)) {
String userName = template
.getForObject("cse://" + USER_SERVICE_NAME + "/validate?token={token}", String.class, token);
if (StringUtils.isNotEmpty(userName)) {
//Add header
invocation.getContext().put(EDGE_AUTHENTICATION_NAME, userName);
} else {
return Response
.failResp(new InvocationException(Status.UNAUTHORIZED, "authentication failed, invalid token"));
}
} else {
return Response.failResp(
new InvocationException(Status.UNAUTHORIZED, "authentication failed, missing AUTHORIZATION header"));
}
}
return null;
}
private boolean isInvocationNeedValidate(String serviceName, String operationPath) {
if (USER_SERVICE_NAME.equals(serviceName)) {
for (String method : NOT_REQUIRED_VERIFICATION_USER_SERVICE_METHODS) {
if (operationPath.startsWith(method)) {
return false;
}
}
}
return true;
}
}
public class LogFilter implements HttpServerFilter {
private static final String LOG_SERVICE_NAME = "infrastructure:log-service";
private final CseAsyncRestTemplate restTemplate = new CseAsyncRestTemplate();
@Override
public int getOrder() {
return 1;
}
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx httpServletRequestEx) {
String userName = invocation.getContext().get(AuthenticationFilter.EDGE_AUTHENTICATION_NAME);
if (StringUtils.isNotEmpty(userName)) {
HttpEntity<LogDTO> request = new HttpEntity<>(
new LogDTO(userName, invocation.getMicroserviceName(), invocation.getOperationName(), new Date()));
try {
restTemplate.postForEntity("cse://" + LOG_SERVICE_NAME + "/record", request, Boolean.class);
} catch (Exception ignored) {
}
}
return null;
}
}
在resource\META-INF\services
目录下,新建org.apache.servicecomb.common.rest.filter.HttpServerFilter
文件,在其中添加:
org.apache.servicecomb.scaffold.edge.filter.AuthenticationFilter
org.apache.servicecomb.scaffold.edge.filter.LogFilter
Edge服务启动后,能够在启动日志中查看到Filter成功加载的信息:
2018-07-16 10:54:11,964 [INFO] Found SPI service org.apache.servicecomb.common.rest.filter.HttpServerFilter, count=4. org.apache.servicecomb.foundation.common.utils.SPIServiceUtils.loadSortedService(SPIServiceUtils.java:76)
2018-07-16 10:54:11,965 [INFO] 0. org.apache.servicecomb.common.rest.filter.inner.ServerRestArgsFilter. org.apache.servicecomb.foundation.common.utils.SPIServiceUtils.loadSortedService(SPIServiceUtils.java:79)
2018-07-16 10:54:11,965 [INFO] 1. org.apache.servicecomb.scaffold.edge.filter.AuthenticationFilter. org.apache.servicecomb.foundation.common.utils.SPIServiceUtils.loadSortedService(SPIServiceUtils.java:79)
2018-07-16 10:54:11,965 [INFO] 2. org.apache.servicecomb.common.rest.filter.tracing.TracingFilter. org.apache.servicecomb.foundation.common.utils.SPIServiceUtils.loadSortedService(SPIServiceUtils.java:79)
2018-07-16 10:54:11,965 [INFO] 3. org.apache.servicecomb.scaffold.edge.filter.LogFilter. org.apache.servicecomb.foundation.common.utils.SPIServiceUtils.loadSortedService(SPIServiceUtils.java:79)