2015-05-19 18 views
22

Tôi hiện đang phát triển một ứng dụng dựa trên kiến ​​trúc dịch vụ vi mô. Chúng tôi sử dụng API-Gateway được triển khai bằng Máy chủ Zuul của Spring Cloud Netfix để định tuyến các yêu cầu đến các dịch vụ vi mô của chúng tôi.Máy chủ ủy quyền OAuth mùa xuân phía sau Spring Cloud Zuul Proxy

Để nhận ra một lần đăng nhập cho tất cả các dịch vụ của chúng tôi, tôi hiện đang làm việc trên một máy chủ OAuth2 được thiết lập bằng cách sử dụng Bảo mật đám mây mùa xuân. Máy chủ về cơ bản chỉ là bản sao và quá khứ của việc triển khai trong Repo của Dave Syer: https://github.com/dsyer/spring-security-angular/tree/master/oauth2/authserver

Sự khác biệt chính là tôi muốn định tuyến các yêu cầu tới máy chủ OAuth của tôi thông qua Proxy Zuul. Bằng cách này, tôi sẽ không phải trực tiếp hiển thị Máy chủ OAuth của mình và có thể thêm và xóa Máy chủ đăng nhập một cách linh hoạt.

Vấn đề là tôi không tìm đường để hiểu cách định cấu hình chính xác thiết lập này. Khi tôi cố truy cập tài nguyên được bảo vệ trên máy chủ OAuth, tôi được chuyển tiếp tới trang đăng nhập. Điều này tất nhiên là như mong đợi. Nhưng tôi không thể tìm ra cách đặt tên máy chủ và cổng được sử dụng khi chuyển tiếp. Những gì tôi muốn xảy ra là máy chủ để chuyển tiếp đến một điểm cuối trên máy chủ Zuul sẽ được proxy trở lại máy chủ OAuth. (Cổng API Zuul phải là máy chủ duy nhất mà khách hàng từng nói chuyện. Mọi thứ khác sẽ bị ẩn.)

Vì máy chủ và cổng được đọc từ HttpServletRequest trong LoginUrlAuthenticationEntryPoint. Nhưng yêu cầu mà máy chủ thấy là yêu cầu gửi bởi proxy Zuul. Vì vậy, tôi được chuyển tiếp đến một IP nội bộ không phải là điểm cuối trên proxy.

Tôi đã cố gắng đặt URL của trang đăng nhập trong WebSecurityConfigurerAdapter.configure(HttpSecurity) thành URL tuyệt đối của Proxy Zuul của tôi. Nhưng điều này chỉ khiến ứng dụng của tôi phàn nàn về quá nhiều chuyển hướng. (Có thể đã gây ra một vòng lặp ở đó.)

Cách tốt nhất để thiết lập điều này là gì?

  • Tôi có phải thực hiện một số loại chiến lược chuyển tiếp riêng bằng cách ghi đè một bean không?
  • Có tùy chọn cấu hình nào bị thiếu không?
  • Ý tưởng của tôi có sai không? (Trong câu trả lời của mình để How to avoid redirect to another host with Zuul? Dave Syer nói rằng bạn sẽ không bình thường proxy này nhưng không giải thích lý do tại sao.)
+0

Vì vậy, cuối cùng làm thế nào để bạn tiến hành với vấn đề này? – wmfairuz

+0

Bạn có thể vui lòng thêm cách bạn sắp xếp và triển khai? – Sourabh

+0

Tôi đã chấp nhận câu trả lời được xếp hạng cao nhất hiện nay. –

Trả lời

13

Cập nhật: POC có thể được tìm thấy ở đây https://github.com/kakawait/uaa-behind-zuul-sample


Bạn hãy thử sau thiết lập (trên zuul server):

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 
     ... 

Về cơ bản nó hoạt động trên dự án của tôi chỉ điều tôi phải làm là tắt bảo vệ CSRF trên tuyến đường /uaa/oauth/token.

Auth máy chủ nên được trên

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

Tested sử dụng Spring-Cloud.Brixton.M3


Thank để @thomas-letsch, bạn nên tinh chỉnh bạn bảo mật như sau (mẫu)

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); 
} 
+0

Điều này cũng phù hợp với tôi. Tôi phải loại trừ đường dẫn/uaa/oauth khỏi bảo mật. Xem phần này từ WebSecurityConfigurerAdapter tôi: –

+0

public void configure (HttpSecurity http) throws Exception { \t \t http.logout() và() .antMatcher ("/ **") authorizeRequests() .antMatchers ("/.. index.html "," /home.html ","/","/uaa/oauth/** "). allowAll() .anyRequest(). authenticated(). và() .csrf(). csrfTokenRepository (getCSRFTokenRepository()). ignoringAntMatchers ("/ uaa/oauth/token") và() .addFilterSau (createCSRFHeaderFilter(), CsrfFilter.class); } –

+0

Trong trường hợp cá nhân của tôi, tôi viết lại 'OAuth2ClientContextFilter' để hỗ trợ' URI' (và không chỉ 'URL'), do đó tôi có thể sử dụng' accessTokenUri:/uaa/oauth/token'. Và đối với 'userAuthorizationUri' tôi sử dụng' localhost' như sau 'userAuthorizationUri: http: // localhost/uaa/oauth/authorize'. Do đó cấu hình là di động (tôi không cần phải biết vị trí của UAA). Tôi đã mở một vấn đề cho https://github.com/spring-projects/spring-security-oauth/issues/671 – Kakawait

2

Theo như tôi hiểu câu hỏi của bạn, spring-cloud-security (đối với EnableOauth2Sso phần) và spring-cloud (ví zuul), điều này không thể ủy quyền các cuộc gọi đến máy chủ ủy quyền bằng zuul. Lý do chính là spring-cloud-security đóng chặt Cổng một cách độc lập (và trước khi tính toán) logic định tuyến Zuul.

Điều đó có nghĩa rằng (cấu hình mẫu từ OAuth2 dụ Dave Syer của) spring.oauth2.client.* cấu hình

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

được coi trước cho phép bất kỳ quyền truy cập vào các tuyến đường của Zuul zuul.routes.*

Hơn nữa thiết lập này cho phép khách hàng đại lý để lưu trữ hai Cookie: một cho Gateway và một cho Máy chủ ủy quyền.

Tôi hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan