3

我正在配置使用Zuul反向代理实用程序的Spring Cloud(Angel.SR6)应用程序,以便隐藏内部服务端口。我的zuul(边缘)服务在8765端口发布,我的组织服务在8083端口。当我没有安全地访问应用程序时,一切都会顺利进行,http://localhost:8765/organization/organizations返回所有组织的JSON。Zuul反向代理与Keycloak服务器

但是,现在我想集成一个Keycloak SSO(OAuth2)服务器用于授权目的。我在我的组织服务中添加了Spring Security adapter,并将其配置为在http://localhost:8080/auth中进行身份验证。一切顺利,除了zuul执行重定向而不是代理。所以当身份验证成功时,我将重定向到http://localhost:8083/organizations而不是http://localhost:8765/organization/organizations。这里有我的浏览器的请求:

enter image description here

这是因为keycloak适配器会在http://localhost:8083/sso/login令牌验证端点,从它以验证令牌执行重定向到授权服务器。当授权服务器确认它时,将重定向发送到组织服务,路径为/organization,因此加载的最终url为http://localhost:8083/organizations。但我想要加载第一个请求的网址。

我有哪些选择?

+0

我可以肯定的一件事是,zuul本身没有重定向,它只转发响应,所以如果下游服务发送重定向,zuul会将其转发给浏览器。 – spencergibb

+0

@spencergibb,我知道,实际上问题在于下游服务,它有一个配置重定向到SSO服务器的登录端点。 SSO服务器接收要重定向到的url作为url参数,如'/ auth/realm/master?redirectUri = http:// localhost:8083/sso/login'。因此,SSO服务器执行重定向到该URL,该URL也会重定向到最终的“http:// localhost:8083/organizations”路径。一个解决方案是只保护zuul服务,所以我会将每个请求重定向到zuul本身,但这会涉及到将其余服务暴露出来。 –

回答

1

最近我遇到了同样的问题。我已经解决了它:

  1. 添加到application.properties在Zuul

    zuul.sensitive报头=饼干,设置Cookie

  2. 在Zuul

    介绍KeycloakFilterRoute
    class KeycloakFilterRoute extends ZuulFilter { 
    
    private static final String AUTHORIZATION_HEADER = "authorization"; 
    
    @Override 
    public String filterType() { 
        return "route"; 
    } 
    
    @Override 
    public int filterOrder() { 
        return 0; 
    } 
    
    @Override 
    public boolean shouldFilter() { 
        return true; 
    } 
    
    @Override 
    public Object run() { 
        RequestContext ctx = RequestContext.getCurrentContext(); 
        if (ctx.getRequest().getHeader(AUTHORIZATION_HEADER) == null) { 
         addKeycloakTokenToHeader(ctx); 
        } 
        return null; 
    } 
    
    private void addKeycloakTokenToHeader(RequestContext ctx) { 
        RefreshableKeycloakSecurityContext securityContext = getRefreshableKeycloakSecurityContext(ctx); 
        if (securityContext != null) { 
         ctx.addZuulRequestHeader(AUTHORIZATION_HEADER, buildBearerToken(securityContext)); 
        } 
    } 
    
    private RefreshableKeycloakSecurityContext getRefreshableKeycloakSecurityContext(RequestContext ctx) { 
        if (ctx.getRequest().getUserPrincipal() instanceof KeycloakAuthenticationToken) { 
         KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) ctx.getRequest().getUserPrincipal(); 
         return (RefreshableKeycloakSecurityContext) token.getCredentials(); 
        } 
        return null; 
    } 
    
    private String buildBearerToken(RefreshableKeycloakSecurityContext securityContext) { 
        return "Bearer " + securityContext.getTokenString(); 
    } 
    

    }

+0

好的意思。为了向keycloak团队解释我的问题,我最终做出了一个Github项目,并得到了一位开发团队成员试图帮助我的请求。这里你有[链接](https://github.com/xtremebiker/zuul-keycloak-test/pull/1),它可能对你有用。根据他们的建议,我得出的结论是zuul很好地隐藏无状态服务(只有持有者),但不是用户直接与之交互的服务。这里是邮件列表中的[整个主题](http://lists.jboss.org/pipermail/keycloak-user/2016-May/006287.html)。 –

相关问题