Spring OAuth授权服务器在Spring Cloud Zuul代理后面

29

我正在开发一个基于微服务架构的应用程序。我们使用了使用Spring Cloud Netflix的Zuul服务器实现的API网关来将请求路由到我们的微服务。

为了实现所有服务的单点登录,我目前正在使用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-Gateway应该是客户端交互的唯一服务器,其他所有内容都将被隐藏。)

现在,主机名和端口是从HttpServletRequest中读取的,并且是在LoginUrlAuthenticationEntryPoint中设置的。但是服务器看到的请求是由Zuul代理发送的请求。因此,我被转发到内部IP而不是代理上的端点。

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

什么是最佳设置方式?

  • 我是否必须通过覆盖bean来实现某种自己的转发策略?
  • 有没有我忽略的配置选项?
  • 我的想法本身是否错误?(在他回答如何避免使用Zuul重定向到另一个主机的问题时,Dave Syer说你通常不会代理这个请求,但没有解释原因。)

最终你打算如何处理这个问题? - wmfairuz
请问您能否添加一下您是如何解决并实现的? - Sourabh
我现在接受了排名最高的答案。 - Tobias Kremer
2个回答

20

更新: 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); 
} 

这对我也起作用。我不得不从安全中排除/uaa/oauth路径。请参阅我的WebSecurityConfigurerAdapter中的此部分: - 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); } - Thomas Letsch
在我的个人案例中,我重写了OAuth2ClientContextFilter以支持URI(而不仅仅是URL),因此我可以使用accessTokenUri:/uaa/oauth/token。对于userAuthorizationUri,我像下面这样使用localhost userAuthorizationUri:http://localhost/uaa/oauth/authorize。因此配置是可移植的(我不需要知道UAA位于何处)。我为此打开了一个问题https://github.com/spring-projects/spring-security-oauth/issues/671 - Kakawait
有趣的方法。我看到,它旨在在zuul服务器本身提供授权点。然而,你在哪里告诉zuul真正的OAuth服务器在哪里呢?我的意思是,你已经在zuul配置中提供了<zuul hostname>以使其能够对自己进行授权,但它如何知道真正的授权终点呢? - Aritz
我创建了一个带有扩展文档的 poc,应该可以回答你之前的问题 https://github.com/kakawait/uaa-behind-zuul-sample - Kakawait
我无法告诉您我花了多长时间才找到这个!而且你正在使用JWT!太棒了!继续保持好工作! - Kent Bull

4
据我理解,对于EnableOauth2Sso部分的内容,需要使用spring-cloud-security(用于安全网关)和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:一个用于网关,另一个用于授权服务器。

希望这可以帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接