javascript
使用Spring Security和OAuth 2.0保护Spring微服务架构
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
每個開發人員都希望能夠更快,更有效地進行構建以支持規模。 使用Spring構建微服務架構可以為您的架構增加彈性和彈性,這將使其優雅地失效并無限擴展。
借助Spring Security及其OAuth 2.0支持,您還可以獲得鎖定API網關以及后端服務器所需的一切。 您可以將其設置為自動將訪問令牌從一個應用程序傳播到另一個應用程序,以確保在此過程中所有內容保持安全和加密。
本教程向您展示如何將Spring Security與OAuth 2.0和Okta結合使用來鎖定您的微服務架構。
帶有Spring Boot + Spring Cloud的微服務架構
本教程將向您展示如何為我之前寫的教程“ 使用Spring Boot為Microbrews構建微服務體系結構”增加安全性。 帶有Spring Boot和Spring Cloud的基本微服務架構如下圖所示。
完成本教程后,您將獲得Spring Security鎖定的一切,Okta將為OAuth提供授權。 您的邊緣服務(也稱為API網關)將具有一個Feign客戶端和一個處理正常故障轉移的Hystrix,該客戶端將隨您的訪問令牌一起傳遞。
首先,您需要克隆上述文章的已完成項目。
git clone https://github.com/oktadeveloper/spring-boot-microservices-example.git在Okta中創建Web應用程序
如果您還沒有,請創建一個永久免費的Okta Developer帳戶 。 完成設置過程后,登錄到您的帳戶并導航至Applications > Add Application 。 單擊Web , 然后單擊下一步 。 在下一頁上,輸入以下值,然后單擊完成 。
- 應用名稱: Spring OAuth
- 基本URI: http://localhost:8081
- 登錄重定向URI: http://localhost:8081/login
記下clientId和client機密值,因為它們將用于配置Spring Boot應用程序。
您需要在ID令牌中添加一個roles聲明,以便將Okta中的組轉換為Spring Security機構。 在Okta開發人員控制臺中,導航到API > 授權服務器 ,單擊授權服務器選項卡并編輯默認選項卡。 點擊索賠標簽,然后添加索賠 。 將其命名為“角色”,并將其包含在ID令牌中。 將值類型設置為“ Groups”,并將過濾器設置為.*的正則表達式。
將Spring Security OAuth添加到邊緣服務應用程序
邊緣服務應用程序處理與beer-catalog-service的通信,因此它是開始集成OAuth的最佳位置。 在edge-service/pom.xml ,添加Spring Security的依賴關系,其OAuth支持和JWT支持。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.1.RELEASE</version> </dependency>將以下Zuul路由添加到edge-service/src/main/resources/application.properties 。
zuul.routes.beer-catalog-service.path=/beers zuul.routes.beer-catalog-service.url=http://localhost:8080zuul.routes.home.path=/home zuul.routes.home.url=http://localhost:8080打開edge-service/src/main/java/com/example/edgeservice/EdgeServiceApplication.java并添加@EnableOAuth2Sso以啟用OAuth身份驗證。
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; ... @EnableOAuth2Sso @SpringBootApplication public class EdgeServiceApplication {添加@EnableOAuth2Sso導致Spring Security查找大量屬性。 將以下屬性添加到edge-service/src/main/resources/application.properties 。
security.oauth2.client.client-id={yourClientId} security.oauth2.client.client-secret={yourClientSecret} security.oauth2.client.access-token-uri=https://{yourOktaDomain}.com/oauth2/default/v1/token security.oauth2.client.user-authorization-uri=https://{yourOktaDomain}.com/oauth2/default/v1/authorize security.oauth2.client.scope=openid profile email security.oauth2.resource.user-info-uri=https://{yourOktaDomain}.com/oauth2/default/v1/userinfo security.oauth2.resource.token-info-uri=https://{yourOktaDomain}.com/oauth2/default/v1/introspect security.oauth2.resource.prefer-token-info=false提示:如果在上面的代碼片段中看到{yourOktaDomain} ,請登錄到Okta帳戶并刷新此頁面。 它將用您的域替換該值。
將ResourceServerConfig.java類添加到與EdgeServiceApplication相同的包中。
package com.example.edgeservice;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;@Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.requestMatcher(new RequestHeaderRequestMatcher("Authorization")).authorizeRequests().antMatchers("/**").authenticated();} }至此,您已經完成了足以登錄到Edge Service應用程序的配置,但是它無法與下游beer-catalog-service進行通信。
將Spring Security OAuth添加到Beer Catalog Service
在beer-catalog-service/pom.xml ,添加與添加到Edge Service相同的依賴項,以及Thymeleaf的依賴項。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.1.RELEASE</version> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>將相同的屬性添加到beer-catalog-service/src/main/resources/application.properties 。
security.oauth2.client.client-id={yourClientId} security.oauth2.client.client-secret={yourClientSecret} security.oauth2.client.access-token-uri=https://{yourOktaDomain}.com/oauth2/default/v1/token security.oauth2.client.user-authorization-uri=https://{yourOktaDomain}.com/oauth2/default/v1/authorize security.oauth2.client.scope=openid profile email security.oauth2.resource.user-info-uri=https://{yourOktaDomain}.com/oauth2/default/v1/userinfo security.oauth2.resource.token-info-uri=https://{yourOktaDomain}.com/oauth2/default/v1/introspect security.oauth2.resource.prefer-token-info=false提示:添加這些屬性的替代方法是使用環境變量。 例如, SECURITY_OAUTH2_CLIENT_CLIENT_ID將是用于指定security.oauth2.client.client-id的環境變量。 使用環境變量將允許您從一個位置更改兩個應用程序的設置。
在beer-catalog-service/src/main/java/com/example/beercatalogservice/HomeController.java創建一個HomeController來呈現用戶信息,以便您可以驗證身份驗證是否正常。
package com.example.beercatalogservice;import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping;import java.security.Principal; import java.util.Map;@Controller public class HomeController {@GetMapping("/home")@SuppressWarnings("unchecked")public String howdy(Model model, Principal principal) {OAuth2Authentication authentication = (OAuth2Authentication) principal;Map<String, Object> user = (Map<String, Object>) authentication.getUserAuthentication().getDetails();model.addAttribute("user", user);return "home";} }在beer-catalog-service/src/main/resources/templates/home.html創建一個home.html模板,并使用以下代碼填充它。
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head><style>th {text-align: left;}td {white-space: nowrap;}td:first-child {font-family: "Courier", monospace;font-size: 0.9em;color: #343434;}</style> </head> <body> <h1>Hello<span th:if="${user}" th:text="' ' + ${user.name}"> Joe</span>!</h1> <div th:unless="${user}"><a th:href="@{/login}">Login</a> </div> <div th:if="${user}"><form id="logoutForm" th:action="@{/logout}" method="post"><input type="submit" value="Logout"/></form> </div><h2>User Properties</h2> <table><thead><tr><th>Name</th><th>Value</th></tr></thead><tbody><tr><td>sub</td><td th:text="${user.sub}"></td></tr><tr><td>name</td><td th:text="${user.name}"></td></tr><tr><td>given_name</td><td th:text="${user.given_name}"></td></tr><tr><td>family_name</td><td th:text="${user.family_name}"></td></tr><tr><td>preferred_username</td><td th:text="${user.preferred_username}"></td></tr><tr><td>email</td><td th:text="${user.email}"></td></tr><tr><td>roles</td><td th:text="${user.roles}"></td></tr></tbody> </table> </body> </html>在與HomeController相同的包中創建ResourceServerConfig.java類。 此類配置Spring Security,因此可以保護所有端點,但那些通過Authorization標頭訪問的端點除外。
package com.example.beercatalogservice;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;@Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.requestMatcher(new RequestHeaderRequestMatcher("Authorization")).authorizeRequests().anyRequest().fullyAuthenticated();} }添加偽裝的RequestInterceptor
用于與beer-catalog-service對話的@FeignClient Authorization標頭。 為了使其UserFeignClientInterceptor ,請在與EdgeServiceApplication相同的目錄中創建UserFeignClientInterceptor類。
package com.example.edgeservice;import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.stereotype.Component;@Component public class UserFeignClientInterceptor implements RequestInterceptor {private static final String AUTHORIZATION_HEADER = "Authorization";private static final String BEARER_TOKEN_TYPE = "Bearer";@Overridepublic void apply(RequestTemplate template) {SecurityContext securityContext = SecurityContextHolder.getContext();Authentication authentication = securityContext.getAuthentication();if (authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) {OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));}} }注冊為@Bean里面EdgeServiceApplication類。
import feign.RequestInterceptor; ... public class EdgeServiceApplication {public static void main(String[] args) {SpringApplication.run(EdgeServiceApplication.class, args);}@Beanpublic RequestInterceptor getUserFeignClientInterceptor() {return new UserFeignClientInterceptor();} }為了使Hystrix了解安全上下文,您需要在edge-service/src/main/resources/application.properties 添加兩個屬性 :
feign.hystrix.enabled=true hystrix.shareSecurityContext=true驗證安全通信
您可以通過啟動所有Spring Boot應用程序來驗證edge-service和beer-catalog-service之間的通信。 首先,啟動eureka-service :
cd eureka-service ./mvnw spring-boot:run在新的終端窗口中,啟動beer-catalog-service :
cd beer-catalog-service ./mvnw spring-boot:run在另一個終端窗口中,啟動edge-service :
cd edge-service ./mvnw spring-boot:run打開瀏覽器并導航到http://localhost:8081/good-beers 。 您應該被重定向到Okta域,并看到一個登錄頁面,提示您輸入憑據。
輸入您用來創建帳戶的憑據,結果將看到一列優質啤酒。
如果您嘗試導航到http://localhost:8081/home ,它將無法正常工作。 這是因為您需要將Spring Cloud Security添加到edge-service/pom.xml以中繼Zuul代理的訪問令牌。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-security</artifactId> </dependency>沒有這種依賴性,對/good-beers請求將可以工作(因為已配置Feign),但對/home請求將不會(因為Zuul需要Spring Cloud Security)。
重新啟動邊緣服務器應用程序,導航到http://localhost:8081/home ,您將在下一頁看到您的用戶詳細信息。
在Spring Boot 2.0中保護下游服務
使用Spring Boot 1.5.x,將Actuator作為依賴項包括在內將觸發Actuator Security并使其受到保護,從而保護了http://localhost:8080 。 在Spring Boot 2.x中,擁有WebSecurityConfigurerAdapter會導致執行器安全性降低。 在Beer Catalog Service應用程序中, ResourceServerConfig導致此行為。
要確保執行器端點安全并使其無法直接訪問http://localhost:8080 ,請在beer-catalog-service/src/main/resources/application.properties添加要公開的端點:
management.endpoints.web.exposure.include=beans,mappings然后創建一個SecurityConfig類(與ResourceServerConfig放在同一包中)。
package com.example.beercatalogservice;import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN").anyRequest().authenticated().and().httpBasic();} }進行這些更改后,重新啟動beer-catalog-service并見證其保護。
注意:由于出現403錯誤,我無法使注銷按鈕正常工作。 我嘗試在邊緣服務應用程序csrf().requireCsrfProtectionMatcher(r -> false)到ResourceServerConfig ,但這沒有幫助。 我給Spring Security團隊發送了一封電子郵件,詢問他們是否有任何建議。
將Okta的登錄小部件添加到Angular客戶端
要使用Okta的登錄小部件,您需要在Okta中修改您的應用以啟用“ 隱式”授予類型。 登錄到您的帳戶,導航至“ 應用程序” >“ Spring OAuth” >“ 常規”選項卡,然后單擊“ 編輯” 。 在“ 允許的授予類型”下啟用“ 隱式(混合)” ,并選中其下方的兩個復選框。 在登錄重定向URI下添加http://localhost:4200 ,然后點擊保存 。
為了使“登錄小部件”向該應用程序發出請求,您還需要將客戶端URL配置為可信來源。 單擊API > 可信 來源 > 添加來源 。 輸入http://localhost:4200作為原始URL,并選中其下方的兩個復選框。
打開一個終端,導航到spring-boot-microservices-example/client ,然后使用npm安裝客戶端的依賴項。
cd client npm install安裝Okta的登錄小部件 ,使其可以與受保護的服務器進行通信。
npm install @okta/okta-signin-widget --save將小部件CSS添加到client/src/styles.css :
@import '~@okta/okta-signin-widget/dist/css/okta-sign-in.min.css'; @import '~@okta/okta-signin-widget/dist/css/okta-theme.css';創建client/src/app/shared/okta/okta.service.ts并使用它來配置小部件以與您的Okta租戶對話。 請確保在下面的代碼中替換{yourOktaDomain}和{clientId} 。
import { Injectable } from '@angular/core'; import * as OktaSignIn from '@okta/okta-signin-widget';@Injectable() export class OktaService {widget;constructor() {this.widget = new OktaSignIn({baseUrl: 'https://{yourOktaDomain}.com',clientId: '{yourClientId}',authParams: {issuer: 'default',responseType: ['id_token', 'token'],scopes: ['openid', 'email', 'profile']}});}getWidget() {return this.widget;}getIdToken() {return this.widget.tokenManager.get('idToken');}getAccessToken() {return this.widget.tokenManager.get('accessToken');} }將OktaService作為提供程序添加到client/src/app/app.module.ts 。
import { OktaService } from './shared/okta/okta.service';@NgModule({...providers: [OktaService],bootstrap: [AppComponent] }) export class AppModule { }修改client/src/app/shared/beer/beer.service.ts以讀取訪問令牌,并將其設置在Authorization標頭中(如果存在)。
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { OktaService } from '../okta/okta.service';@Injectable() export class BeerService {constructor(private http: HttpClient, private oktaService: OktaService) {}getAll(): Observable {let headers: HttpHeaders = new HttpHeaders();if (this.oktaService.getAccessToken()) {const accessToken = this.oktaService.getAccessToken();// headers is immutable, so re-assignheaders = headers.append('Authorization', accessToken.tokenType + ' ' + accessToken.accessToken);}return this.http.get('http://localhost:8081/good-beers', {headers: headers});} }修改app.component.html ,為小部件添加一個占位符,并顯示一個部分,以顯示用戶名和注銷按鈕。
<mat-toolbar color="primary"><span>Welcome to {{title}}!</span> </mat-toolbar><!-- Container to inject the Sign-In Widget --> <div id="okta-signin-container"></div><div *ngIf="user"><h2>Welcome {{user?.name}}!</h2><button mat-raised-button (click)="logout()">Logout</button><app-beer-list></app-beer-list> </div>您會注意到HTML中的user變量。 要解決此問題,您需要更改client/src/app/app.component.ts以使其呈現登錄小部件。 Angular的ChangeDetectorRef用于在事物發生更改并且渲染需要處理更新的變量時通知Angular。
import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { OktaService } from './shared/okta/okta.service';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit {title = 'app';user;signIn;constructor(private oktaService: OktaService, private changeDetectorRef: ChangeDetectorRef) {this.signIn = oktaService.getWidget();}showLogin() {this.signIn.renderEl({el: '#okta-signin-container'}, (response) => {if (response.status === 'SUCCESS') {response.forEach(token => {if (token.idToken) {this.signIn.tokenManager.add('idToken', token);this.user = this.getUser(token);}if (token.accessToken) {this.signIn.tokenManager.add('accessToken', token);}});this.signIn.remove();this.changeDetectorRef.detectChanges();}});}getUser(token) {return {name: token.claims.name,email: token.claims.email,username: token.claims.preferred_username};}ngOnInit() {this.signIn.session.get((response) => {if (response.status !== 'INACTIVE') {const token = this.oktaService.getIdToken();this.user = this.getUser(token);this.changeDetectorRef.detectChanges();} else {this.showLogin();}});}logout() {this.signIn.signOut(() => {this.user = undefined;this.changeDetectorRef.detectChanges();this.showLogin();});} }為了使BeerListComponent (在src/app/beer-list/beer-list.component.ts )來檢測你已經登錄,您需要使用添加在構造函數依賴ChangeDetectorRef并調用它的detectChanges()方法時您可以在每種beer上設置giphyUrl屬性。
import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { BeerService, GiphyService } from '../shared';@Component({selector: 'app-beer-list',templateUrl: './beer-list.component.html',styleUrls: ['./beer-list.component.css'],providers: [BeerService, GiphyService] }) export class BeerListComponent implements OnInit {beers: Array<any>;constructor(private beerService: BeerService, private giphyService: GiphyService,private changeDetectorRef: ChangeDetectorRef) { }ngOnInit() {this.beerService.getAll().subscribe(data => {this.beers = data;for (const beer of this.beers) {this.giphyService.get(beer.name).subscribe(url => {beer.giphyUrl = url;this.changeDetectorRef.detectChanges();});}},error => console.log(error))} }驗證身份驗證作品
通過打開終端,導航到client目錄,然后運行npm start client 。 將瀏覽器打開到http://localhost:4200 ,您應該看到類似以下的登錄表單。
如果要調整表單的樣式,以免它與頂部工具欄不對,請在styles.css添加以下內容。
#okta-signin-container {margin-top: 25px; }
您應該能夠登錄,看到歡迎消息以及注銷按鈕。 但是,由于控制臺中出現以下錯誤,您不會看到啤酒清單。
發生這種情況是因為Spring Security無法識別/good-beers端點上的@CrossOrigin批注。 要解決此問題,請向EdgeServiceApplication添加一個simpleCorsFilter 。
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;import java.util.Collections; ... public class EdgeServiceApplication {public static void main(String[] args) {SpringApplication.run(EdgeServiceApplication.class, args);}@Beanpublic RequestInterceptor getUserFeignClientInterceptor() {return new UserFeignClientInterceptor();}@Beanpublic FilterRegistrationBean simpleCorsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.setAllowedOrigins(Collections.singletonList("*"));config.setAllowedMethods(Collections.singletonList("*"));config.setAllowedHeaders(Collections.singletonList("*"));source.registerCorsConfiguration("/**", config);FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));bean.setOrder(Ordered.HIGHEST_PRECEDENCE);return bean;} }重新啟動邊緣服務應用程序,然后重試。 這次您應該取得巨大的成功!
注意:如果在生產中使用此配置,則應將允許的來源從*更改為客戶的URL。
部署到Cloud Foundry
要使用Pivotal Web Services在Cloud Foundry上部署所有內容,您需要創建一個帳戶,下載/安裝Cloud Foundry CLI并登錄(使用cf login -a api.run.pivotal.io )。
部署所有服務和Angular客戶端要進行生產涉及很多步驟。 因此,我編寫了一個deploy.sh腳本來自動執行所有操作。
注意:該腳本完成后,您必須將客戶端的URL作為登錄重定向URI添加到Okta應用中。 您還需要在API > Trusted Origins下將其添加為源 。
提示:如果收到錯誤消息,說明您使用的內存過多,則可能必須升級Cloud Foundry訂閱。
進一步了解Spring Boot,OAuth 2.0和微服務
本文向您展示了如何使用Spring Security,OAuth和Okta保護微服務架構。 借助Zuul,Feign和Spring Cloud Security,您可以確保后端服務安全地通信。
本教程的源代碼位于GitHub的“ oauth”分支中 。
git clone https://github.com/oktadeveloper/spring-boot-microservices-example.git git checkout oauth本教程向您展示了如何在上一教程“ 使用Spring Boot為Microbrews構建微服務架構 ”中增加安全性。
如果您有興趣了解Spring Security和OAuth 2.0的未來,請參閱我們的Spring Security團隊的好朋友Joe Grandja提供的有關Spring Security的下一代OAuth 2.0支持 。
此外,JHipster對其OAuth支持使用相同的設置。 如果您對將Okta與JHipster結合使用感興趣,建議您閱讀以下博客文章:
- 使用OAuth 2.0和JHipster開發微服務架構
- 使用Ionic for JHipster創建具有OIDC身份驗證的移動應用程序
在developer.okta.com/product上了解有關Okta及其API的更多信息。 如果您對本教程有疑問,請在下面發表評論或在Twitter @mraible上打我。
變更日志:
- 2018年5月11日:更新為使用Spring Boot 2.0和Okta登錄小部件2.0.8。 請參閱spring-boot-microservices-example#17中的示例應用程序更改; 可以在okta.github.io#2049中查看對此帖子的更改。
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
使用Spring Security和OAuth 2.0保護Spring微服務體系結構最初于2018年2月13日發布在Okta開發者博客上。
翻譯自: https://www.javacodegeeks.com/2018/05/secure-a-spring-microservices-architecture-with-spring-security-and-oauth-2-0.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的使用Spring Security和OAuth 2.0保护Spring微服务架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PCL 实战记录 (一)
- 下一篇: 用于在Synology NAS上测试Sp