【问题标题】:Authentication to access Spring boot Zuul Service routes访问 Spring boot Zuul Service 路由的身份验证
【发布时间】:2018-01-12 15:13:43
【问题描述】:

我已经使用 Spring boot zuul 和 eureka 服务配置了我的微服务。 现在我需要对所有路由/REST API 调用进行身份验证。 我的意思是,对于所有 API,客户端发送一个 accessToken。 在 zuul 服务上,在路由到特定服务之前,我必须使用 accessToken 调用微服务(auth-service),并且该 auth-service 将检查用户是否存在发送的 accessToken。 如果 accessToken 有效,则只发生路由。

请帮助我使用 Spring Boot 服务实现这一点。

谢谢。

【问题讨论】:

  • 您的 accessToken 不是您可以信任的签名令牌吗?
  • spring-security 是正确执行此操作的方法。仅当您知道调用者无法绕过您的代理并直接访问微服务时,您才应该这样做。
  • @Andy Brown,您能否提供详细信息或链接查看?

标签: spring-mvc spring-boot microservices netflix-eureka netflix-zuul


【解决方案1】:

您需要编写一个过滤器。 zuul pre 过滤器是您所需要的。您可以在过滤器中访问您的身份验证服务器,如果令牌无效,您不会调用您的微服务并立即返回响应。如果它是有效的,你让请求去到微服务。

一个示例过滤器类:

public class AuthFilter extends ZuulFilter {

    @Autowired
    RestTemplate restTemplate;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        //get your token from request context and send it to auth service via rest template
        boolean validToken = restTemplate.exchange(or getForObject or other methods of restTemplate which you find suitable for method and return type of your auth service controller method)
        if(!validToken) {
            ctx.setSendZuulResponse(false); //This makes request not forwarding to micro services
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            ValidationResponse validationResponse = new ValidationResponse();
            validationResponse.setSuccess(false);
            validationResponse.setMessage("Invalid Access...");
            ObjectMapper mapper = new ObjectMapper();
            String responseBody = mapper.writeValueAsString(validationResponse);
            ctx.setResponseBody(validationResponse);
            ctx.getResponse().setContentType("application/json");
            //If you want to do any thing else like logging etc, you can do it.
        }
        return null;
    }

}

【讨论】:

  • 感谢您的回复。我可以将响应设置为字符串。 ctx.setResponseBody("无效访问...!");我需要将响应主体设置为自定义对象,如 ValidationResponse。 ValidationResponse 是我对所有服务的唯一响应对象。如下所示:validationResponse.setSuccess(false); validationResponse.setMessage("无效访问...");然后将此 validationResponse 设置为响应对象。你能帮忙吗??
  • @Krishna,没问题,你只需要设置requestContext responseBody。我更新了答案。(我将内容类型设置为json。如果您使用xml,则可以相应地设置内容类型)
  • 不,com.netflix.zuul.context.RequestContext.setResponseBody() 只支持字符串数据类型。
  • @Krishna 对不起,我忘了说你需要转换你的对象。我马上补充。我在我的项目中使用了 com.fasterxml.jackson.databind.ObjectMapper。如果你愿意,你可以使用另一个。这里的技巧是设置内容类型并相应地转换你的对象
  • 谢谢。它按预期适用于 application/json 。但不适用于应用程序/xml。下面是检查: String responseBody = mapper.writeValueAsString(validationResponse); ctx.setResponseBody(responseBody); if(request.getContentType().equalsIgnoreCase("application/json")){ ctx.getResponse().setContentType("application/json"); } if(request.getContentType().equalsIgnoreCase("application/xml")){ ctx.getResponse().setContentType("application/xml"); } 它总是给出 json 字符串。请告诉我如何处理 xml ??
猜你喜欢
  • 1970-01-01
  • 2019-02-13
  • 2020-10-25
  • 2020-02-06
  • 2019-04-25
  • 2018-02-27
  • 2017-04-12
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多