因爲leader要求在搭好的spring cloud 框架中加入對微服務的認證包括單點登陸認證,來確保系統的安全,因此研究了Spring Cloud Security這個組件。在前面搭好的demo中,如何確保微服務的安全,爲整個系統添加安全控制,就須要用到Spring Cloud Security。用戶經過服務網關zuul來訪問任何一個微服務的時候,都須要跳轉到第三方的認證好比github或者本身搭好的CAS單點登陸服務,當認證經過才能訪問對應的服務。在研究spring cloud security 以前先對一些概念進行了解了。
OAuth2(重點),參考文檔:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
Spring Security OAuth2,參考文檔:http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-security-oauth2
html
在這個文章中主要記錄當用戶經過服務網關zuul入口訪問任何一個微服務。須要先跳轉到GitHub,使用Github進行認證,認證經過以後才能跳轉到訪問咱們提供的微服務。git
(1) 前往https://github.com/settings/developers
,點擊「Register a new application」按鈕,添加一個應用。點擊按鈕後,界面以下圖所示。Homepage URL 和callback url是寫zuul的端口。
(2) 點擊「Register application」按鈕,便可出現以下圖的界面。
記住這邊的Client ID以及Client Secret,後面有用。
至此,準備工做就完成了。github
代碼測試成功以後的Github地址:https://github.com/LoveIpo/spring-cloud-demo/tree/master/Zuul_CAS
這個Zuul_CAS是在zuul中進一步完善!spring
在這裏,咱們正式進行編碼。由於我是在服務網關zuul中添加單點登陸的服務認證受權。因此對前面demo中的zuul 工程進一步完善。
(1) 在pom.xml文件爲應用添加spring-cloud-starter-oauth二、spring-cloud-starter-security兩個依賴。api
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> </dependencies>
(2) 在zuul的啓動類中添加以下代碼安全
@SpringBootApplication @EnableZuulProxy @RestController public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } @GetMapping("/") public String welcome() { return "welcome"; } @RequestMapping("/user") public Principal user(Principal user) { return user; } @Component @EnableOAuth2Sso // 實現基於OAuth2的單點登陸,建議跟蹤進代碼閱讀如下該註解的註釋,頗有用 public static class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http. antMatcher("/**") // 全部請求都得通過認證和受權 .authorizeRequests().anyRequest().authenticated() .and().authorizeRequests().antMatchers("/","/anon").permitAll() .and() // 這裏之因此要禁用csrf,是爲了方便。 // 不然,退出連接必需要發送一個post請求,請求還得帶csrf token // 那樣我還得寫一個界面,發送post請求 .csrf().disable() // 退出的URL是/logout .logout().logoutUrl("/logout").permitAll() // 退出成功後,跳轉到/路徑。 .logoutSuccessUrl("/login"); } } }
如代碼所示,在這裏,咱們使用@EnableOAuth2Sso 註解,啓用了「基於OAuth2的單點登陸」,作了一些安全配置;同時,還定義了兩個端點,/ 端點返回「welcome」字符串,/user 端點返回當前登陸用戶的認證信息。session
這裏說明一下,@EnableOAuth2Sso註解。若是WebSecurityConfigurerAdapter類上註釋了@EnableOAuth2Sso註解,那麼將會添加身份驗證過濾器和身份驗證入口。若是隻有一個@EnableOAuth2Sso註解沒有編寫在WebSecurityConfigurerAdapter上,那麼它將會爲全部路徑啓用安全,而且會在基於HTTP Basic認證的安全鏈以前被添加。詳見@EnableOAuth2Sso的註釋。
(3) 修改zuul 的application.yml文件,部分代碼以下app
server: port: 7073 security: user: password: user # 直接登陸時的密碼 ignored: / sessions: never # session策略 oauth2: sso: loginPath: /login # 登陸路徑 client: clientId: 你的clientId clientSecret: 你的clientSecret accessTokenUri: https://github.com/login/oauth/access_token userAuthorizationUri: https://github.com/login/oauth/authorize resource: userInfoUri: https://api.github.com/user preferTokenInfo: false spring: application: name: zuul eureka: client: serviceUrl: defaultZone: http://localhost:7071/eureka/
這樣,經過服務網關zuul來訪問任何一個服務都要跳轉到github進行認證的主要代碼就編寫完成了。框架
(1) 啓動Eureka、zuul、serviceA
(2) 當經過服務網關zuul(端口7073) 訪問serviceA 的url:http://localhost:7073/api-a/add?a=111&b=113
時。頁面會自動跳轉到github進行認證。
你也能夠經過zuul訪問serviceB也會自動跳轉到github進行認證以後才能回調到serviceB。
(3) 當輸入github的用戶名和密碼認證經過以後,會出現serviceA的調用結果。以下圖所示
(4) 當你認證經過以後輸入http://localhost:7073/user
能夠看到你github 的用戶信息。ide