如何在Zuul API网关中添加accessToken身份验证?

时间:2017-10-31 12:09:44

标签: spring-boot spring-security netflix-zuul

我想验证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;
                }
            }

我觉得这不是一种有效的方法。有没有其他方法来实现这种情况? 感谢。

0 个答案:

没有答案