简体   繁体   English

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

[英]Spring OAuth Authorization Server behind Spring Cloud Zuul Proxy

I am currently developing a application based on a micro service architecture. 我目前正在开发基于微服务架构的应用程序。 We use a API-Gateway implemented using Spring Cloud Netfix's Zuul Server to route the requests to our micro services. 我们使用使用Spring Cloud Netfix的Zuul Server实现的API网关将请求路由到我们的微服务。

To realize single sign on for all our services I am currently working on an OAuth2 server set up using Spring Cloud Security. 要实现我们所有服务的单点登录,我目前正在使用Spring Cloud Security设置OAuth2服务器。 The server is basically just copy and past of the implementation in Dave Syer's Repo: https://github.com/dsyer/spring-security-angular/tree/master/oauth2/authserver 服务器基本上只是在Dave Syer的Repo中实现的复制和过去: https//github.com/dsyer/spring-security-angular/tree/master/oauth2/authserver

The main difference is that I want to route the requests to my OAuth server through the Zuul Proxy. 主要区别在于我想通过Zuul代理将请求路由到我的OAuth服务器。 This way I will not have to directly expose my OAuth Server and can add and remove Login Server dynamically. 这样我就不必直接暴露我的OAuth服务器,并可以动态添加和删除Login Server。

The problem is I do not seam to understand how to correctly configure this setup. 问题是我不了解如何正确配置此设置。 When I try to access a protected resource on the OAuth server I am forwarded to the login page. 当我尝试访问OAuth服务器上的受保护资源时,我将转发到登录页面。 This of course is as expected. 这当然是预期的。 But I can not figure out how to set the hostname and port used when forwarding. 但我无法弄清楚如何设置转发时使用的主机名和端口。 What I want to happen is the server to forward to an endpoint on the Zuul server that will get proxied back to the OAuth server. 我想要发生的是服务器转发到Zuul服务器上的端点,该端点将被代理回到OAuth服务器。 (The Zuul API-Gateway should be the only server the client ever talks to. Everything else will be hidden.) (Zuul API-Gateway应该是客户端与之交谈的唯一服务器。其他所有内容都将被隐藏。)

As it is the host and port are read from the HttpServletRequest in LoginUrlAuthenticationEntryPoint . 因为它是从LoginUrlAuthenticationEntryPointHttpServletRequest读取主机和端口。 But the request the server sees is the request send by the Zuul proxy. 但是服务器看到的请求是Zuul代理发送的请求。 So I am forwarded to an internal IP not an endpoint on the proxy. 所以我被转发到内部IP而不是代理端点。

I tried to set the URL of the login page in WebSecurityConfigurerAdapter.configure(HttpSecurity) to the absolut URL of my Zuul Proxy. 我尝试将WebSecurityConfigurerAdapter.configure(HttpSecurity)中的登录页面的URL设置为我的Zuul代理的绝对URL。 But this just caused my application to complain about too many redirects. 但这只是导致我的应用程序抱怨太多的重定向。 (Might have caused a loop there.) (可能会在那里引起循环。)

What would be the best way to set this up? 设置它的最佳方法是什么?

  • Do I have to implement some kind of own forwarding strategy by overriding a bean? 我是否必须通过覆盖bean来实现某种自己的转发策略?
  • Is there a configuration option I am missing? 是否有我缺少的配置选项?
  • Is my idea itself wrong? 我的想法本身是错的吗? (In his answer to How to avoid redirect to another host with Zuul? Dave Syer says you would not normally proxy this but does not explain why.) (在他如何避免与Zuul重定向到另一个主机的回答中 Dave Syer说你通常不代理这个,但不能解释原因。)

Update : POC can be found here https://github.com/kakawait/uaa-behind-zuul-sample 更新 :POC可以在这里找到https://github.com/kakawait/uaa-behind-zuul-sample


Did you try following setup (on zuul server): 您是否尝试过以下设置(在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
      ...

Basically it works on my project only thing I have to do is to disable CSRF protection on /uaa/oauth/token route. 基本上它只适用于我的项目我只需要在/uaa/oauth/token路由上禁用CSRF保护。

Auth server should be on Auth服务器应该打开

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

Tested using Spring-Cloud.Brixton.M3 使用Spring-Cloud.Brixton.M3测试


Thank to @thomas-letsch , you should tweak you security like following (sample) 感谢@ 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); 
} 

As far as I understand your question, spring-cloud-security (for the EnableOauth2Sso part) and spring-cloud (for zuul), this is not possible to proxy the calls to the authorization server using zuul. 据我所知,你的问题是spring-cloud-security (对于EnableOauth2Sso部分)和spring-cloud (对于zuul),这是不可能使用zuul代理对授权服务器的调用。 The main reason being that spring-cloud-security secures the Gateway independently (and before accounting for) Zuul routing's logic. 主要原因是spring-cloud-security独立地(并且在考虑之前)确保了Zuul路由的逻辑。

Which means that the (sample configuration from Dave Syer's OAuth2 example) spring.oauth2.client.* configuration 这意味着(来自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

is considered before allowing any access to the Zuul's routes zuul.routes.* 允许任何访问Zuul的路线zuul.routes.* 之前考虑zuul.routes.*

Moreover this setup enables the client agent to store two Cookies: one for the Gateway and one for the Authorization Server. 此外,此设置使客户端代理能够存储两个Cookie:一个用于网关,另一个用于授权服务器。

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM