我想验证Zuul Gateway的所有请求。例如,每个API请求都会发送accessToken,zuul应该对accessToken进行身份验证。
我通过扩展ZuulFilter来实现这一点。 我的代码如下:
@Component
public class ZuulPreFilter extends ZuulFilter {
@Autowired
private DiscoveryClient discoveryClient;
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER + 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String accessToken = request.getParameter("accessToken");
if (accessToken == null || accessToken.isEmpty()) {
return sendUnauthorizedResponse(ctx, request, "Required AccessToken");
}
List<ServiceInstance> instances = this.discoveryClient.getInstances("security_service");
if (instances != null && instances.size() > 0) {
ServiceInstance securityService = instances.get(0);
String authAccessTokenAPI = securityService.getUri().toString().concat("/users/?accessToken=")
.concat(accessToken);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<ValidationResponse> response = restTemplate.getForEntity(authAccessTokenAPI,
ValidationResponse.class);
ValidationResponse authUserResponse = response.getBody();
if (authUserResponse == null || !authUserResponse.isSuccess()) {
return sendUnauthorizedResponse(ctx, request, "Invalid AccessToken");
}
}
return null;
}
private Object sendUnauthorizedResponse(RequestContext ctx, HttpServletRequest request, String responseMessage) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
ValidationResponse validationResponse = new ValidationResponse();
validationResponse.setSuccess(false);
validationResponse.setMessage(responseMessage);
String contentType = request.getContentType();
if (contentType == null) {
contentType = MediaType.APPLICATION_JSON;
}
// To handle Json contentType
if (contentType.equalsIgnoreCase(MediaType.APPLICATION_JSON)) {
ObjectMapper mapper = new ObjectMapper();
try {
String responseBody = mapper.writeValueAsString(validationResponse);
ctx.setResponseBody(responseBody);
ctx.getResponse().setContentType(MediaType.APPLICATION_JSON);
} catch (JsonProcessingException e) {
}
}
// To handle XML contentType
if (contentType.equalsIgnoreCase(MediaType.APPLICATION_XML)) {
String responseBody = XmlUtil.marshal(validationResponse);
ctx.setResponseBody(responseBody);
ctx.getResponse().setContentType(MediaType.APPLICATION_XML);
}
return ctx;
}
}
我觉得这不是一种有效的方法。有没有其他方法来实现这种情况? 感谢。