Spring Spring Cloud Zuul Proxy 背后的 OAuth 授权服务器

Spring OAuth Authorization Server behind Spring Cloud Zuul Proxy

我目前正在开发一个基于微服务架构的应用。我们使用 API-Gateway 实现,该网关使用 Spring Cloud Netfix 的 Zuul 服务器将请求路由到我们的微服务。

为了实现我们所有服务的单点登录,我目前正在使用 Spring Cloud Security 设置 OAuth2 服务器。服务器基本上只是 Dave Syer 的 Repo 中实现的复制和过去:https://github.com/dsyer/spring-security-angular/tree/master/oauth2/authserver

主要区别在于我想通过 Zuul 代理将请求路由到我的 OAuth 服务器。这样我就不必直接公开我的 OAuth 服务器,并且可以动态添加和删除登录服务器。

问题是我不明白如何正确配置此设置。当我尝试访问 OAuth 服务器上受保护的资源时,我被转发到登录页面。这当然在意料之中。但是我不知道如何设置转发时使用的主机名和端口。我想要发生的是服务器转发到 Zuul 服务器上的端点,该端点将被代理回 OAuth 服务器。 (Zuul API-网关应该是客户端与之通信的唯一服务器。其他所有内容都将被隐藏。)

因为它是从 LoginUrlAuthenticationEntryPoint 中的 HttpServletRequest 读取主机和端口。但是服务器看到的请求是Zuul代理发送的请求。所以我被转发到一个内部 IP 而不是代理上的端点。

我试图将 WebSecurityConfigurerAdapter.configure(HttpSecurity) 中登录页面的 URL 设置为我的 Zuul 代理的绝对 URL。但这只会导致我的应用程序抱怨重定向太多。 (可能在那里造成了循环。)

最好的设置方法是什么?

据我了解你的问题,spring-cloud-security(对于 EnableOauth2Sso 部分)和 spring-cloud(对于 zuul),这是不可能代理对授权的调用服务器使用 zuul。 主要原因是 spring-cloud-security 独立地保护网关(并在考虑之前)Zuul 路由的逻辑。

这意味着(来自 Dave Syer 的 OAuth2 示例的示例配置)spring.oauth2.client.* 配置

spring:
  oauth2:
    client:
      accessTokenUri: http://localhost:9999/uaa/oauth/token
      userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
      clientId: acme
      clientSecret: acmesecret

被认为之前允许任何对 Zuul 路由的访问 zuul.routes.*

此外,此设置使客户端代理能够存储两个 Cookie:一个用于网关,一个用于授权服务器。

希望对您有所帮助。

更新:可以在此处找到 POC https://github.com/kakawait/uaa-behind-zuul-sample


您是否尝试过以下设置(在 zuul 服务器上):

zuul:
  routes:
    uaa-service:
      path: /uaa/**
      stripPrefix: false

security:
  # Disable Spring Boot basic authentication
  basic:
    enabled: false
  oauth2:
    sso:
      loginPath: /login
    client:
      accessTokenUri: https://<zuul hostname>/uaa/oauth/token
      userAuthorizationUri: https://<zuul hostname>/uaa/oauth/authorize
      ...

基本上它适用于我的项目,我唯一要做的就是禁用 /uaa/oauth/token 路由上的 CSRF 保护。

授权服务器应该开启

server:
  # Use different context-path to avoid session cookie overlapping
  context-path: /uaa

使用Spring-Cloud.Brixton.M3

测试

感谢 @thomas-letsch,您应该像下面这样调整您的安全性(样本)

public void configure(HttpSecurity http) throws Exception { 
    http.logout().and()
        .antMatcher("/**").authorizeRequests() 
        .antMatchers("/index.html", "/home.html", "/", "/uaa/oauth/**").permitAll() 
        .anyRequest().authenticated().and() 
        .csrf().csrfTokenRepository(getCSRFTokenRepository()).ignoringAntMatchers("/uaa/‌​oauth/token").and() 
        .addFilterAfter(createCSRFHeaderFilter(), CsrfFilter.class); 
}