当前位置: 首页 > 知识库问答 >
问题:

如果下游服务响应 401,如何在 Zuul API 网关中触发 OAuth2 身份验证

邹铭
2023-03-14

我正在试验三个 Spring 云(启动)应用程序。

    < li >端口9999上的认证服务器 < li >在端口9008上有安全和不安全endpoint的基本后端示例 < li >一个基本的Zuul API网关,有几个路由(安全的和不安全的)到后端-端口9000上的示例

后端示例引导应用程序注释为资源服务器(@EnableResourceServer),并使用ResourceServerConfigurerAdapter保护某些endpoint

当我第一次调用Zuul API网关上受保护的路由之一时,我被重定向到身份验证服务器的登录页面。登录后,我被重定向到我最初请求的安全路由。安全后端示例endpoint的行为与预期一致,这意味着后端示例确实获得了所提供令牌的授予角色。如果我访问了我没有合适角色的后端示例endpoint,我会得到OAuth 403响应。在这种情况下一切正常。

我们还需要将遗留服务放在API网关的后面。这些呈现html,应该能够在用户点击安全区域时触发登录。我们不能在API网关路由级别保护这些区域,因为遗留的后端对于许多不同的子URL有复杂的(增长的)许可模型。

有谁知道在这种下游 401 响应情况下使 Spring-cloud API 网关重定向到身份验证服务器登录的好方法?我尝试在类型为“post”的 ZuulFilter 中进行简单的重定向,但失败了,因为响应已经在那里提交。

后端样本application.yml;

html prettyprint-override">server:
    port: 9008
    
security:
  oauth2:
    resource:
      userInfoUri: http://localhost:9999/uaa/user

API 网关应用程序.yml:

server:
    port: 9008
zuul:
   proxy:
      addProxyHeaders: true
   sensitive-headers: 
   routes:
      unsecured-backend-sample:
         path: /unsecured-backend-sample/**
         url: http://localhost:9008
      authorized-backend-sample:
         path: /authorized-backend-sample/**
         url: http://localhost:9008/
      user-role-secured-backend-sample:
         path: /user-role-secured-backend-sample/**
         url: http://localhost:9008/
      xxx-role-secured-backend-sample:
         path: /xxx-role-secured-backend-sample/**
         url: http://localhost:9008/
security:
  oauth2:
    client:
      accessTokenUri: http://localhost:9999/uaa/oauth/token
      userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
      clientId: acme
      clientSecret: acmesecret
    resource:
      userInfoUri: http://localhost:9999/uaa/user

共有1个答案

锺离逸春
2023-03-14

我终于找到了一个对我有用的解决方案。我写了一个 ZuulFilter 只处理 401 响应并重定向到登录。它还将被拒绝的请求保存在 HTTP 会话请求缓存中,以便 SavedRequestAwareAuthenticationSuccessHandler 可以将您重定向回最初请求的下游服务 URL。

@Component
public class LoginOnDownstreamUnauthorizedResponseFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private AuthenticationEntryPoint authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/login");

    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public boolean shouldFilter() {
        // Only handle downstream 401s
        return RequestContext.getCurrentContext().getResponse().getStatus() == HttpStatus.SC_UNAUTHORIZED;
    }

    @Override
    public Object run() {

        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();

        // We need to put the rejected request in the request cache for SavedRequestAwareAuthenticationSuccessHandler
        // to find it's way back to the initial request URI after successful authentication.
        requestCache.saveRequest(request, response);

        String text = String.format("Downstream service %s responded with a status code 401.", request.getRequestURI());
        logger.debug(text + " Calling Authentication entry point.");
        try {
            authenticationEntryPoint.commence(request, response, new InsufficientAuthenticationException(text));
        } catch (IOException | ServletException e) {
            logger.error("Failed to redirect to Authentication entry point", e);
        }

        return null;
    }

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

    @Override
    public int filterOrder() {
        // make sure to run before SendResponseFilter
        return 500;
    }

}
 类似资料:
  • 这是我使用的授权标头: 以下是我使用的基本字符串: 以下是我的推特文档: 步骤1:获取特殊请求令牌 首先,您使用应用程序的使用者密钥向Twitter请求令牌URLhttps://api.twitter.com/oauth/request_token发出HTTPS请求。除了传统的oauth_*签名参数之外,您还必须包含设置为reverse_auth值的x_auth_mode。 例如,考虑使用令牌秘密

  • 我在我的应用程序中集成了twitter并发布了它。但现在twitter出现了一个问题。在调试期间,我在logcat中遇到了以下异常 06-24 11:23:49.286: W/System.err(27752): 401:身份验证凭据(https://dev.twitter.com/pages/auth)丢失或不正确。确保已设置有效的用户密钥/秘密、访问令牌/秘密,并且系统时钟处于同步状态。06-

  • 我试图代表应用程序,而不是登录到它的用户,从我的应用程序到ADO,执行一个服务到服务的ADO REST调用。 Microsoft提供RESTAPI来执行创建发布管道之类的操作。请参见此处: https://docs.microsoft.com/en-us/rest/api/azure/devops/release/releases/create?view=azure-devops-rest-5.1

  • 问题内容: 在flask中,我使用以下代码段启用HTTP身份验证: 现在,根据我过去使用Flask的经验,如果某人的凭据不正确,我想让他们知道我可以打电话给: 这为你提供了基本的apache 401响应。有谁知道我如何使用上面的代码片段实现这一目标? 谢谢 问题答案: 在Flask中,自定义错误响应确实非常容易。创建一个仅将参数作为HTTP错误状态代码的函数,使其返回flask.Response实

  • 我现在读了很多关于微服务的书,但仍然不了解其中的一些部分。我画了以下图: 每个微服务有2个访问: REST:对于超文本传输协议使用 gRPC:用于内部/后台通信/交换 如果我想登录,我可以向我的身份验证服务发送一个Http请求。但是,如果我想访问需要您连接的Stuff服务,该怎么办? 假设用户希望显示数据库中可用的内容,服务人员将首先通过与身份验证服务交换来检查连接用户的“令牌”是否正确,然后返回

  • 我使用的是Spring Boot(1.2.6)和Spring Security(4.0.2)。 安全配置如下所示: