OAuth 2.0 資源伺服器多租戶
多租戶
當存在多種策略根據某個租戶識別符號驗證不記名令牌時,資源伺服器被視為多租戶。
例如,您的資源伺服器可以接受來自兩個不同授權伺服器的不記名令牌。或者,您的授權伺服器可以代表多個頒發者。
在每種情況下,都需要完成兩件事,並且您選擇如何完成它們會帶來權衡:
-
解析租戶。
-
傳播租戶。
透過宣告解析租戶
區分租戶的一種方法是根據頒發者宣告。由於頒發者宣告伴隨已簽名的 JWT,您可以使用 JwtIssuerReactiveAuthenticationManagerResolver 來實現這一點。
-
Java
-
Kotlin
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = JwtIssuerReactiveAuthenticationManagerResolver
.fromTrustedIssuers("https://idp.example.org/issuerOne", "https://idp.example.org/issuerTwo");
http
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
)
.oauth2ResourceServer((oauth2) -> oauth2
.authenticationManagerResolver(authenticationManagerResolver)
);
val customAuthenticationManagerResolver = JwtIssuerReactiveAuthenticationManagerResolver
.fromTrustedIssuers("https://idp.example.org/issuerOne", "https://idp.example.org/issuerTwo")
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
oauth2ResourceServer {
authenticationManagerResolver = customAuthenticationManagerResolver
}
}
這很好,因為頒發者端點是延遲載入的。事實上,只有當第一個帶有相應頒發者的請求被髮送時,才會例項化相應的 JwtReactiveAuthenticationManager。這使得應用程式啟動獨立於這些授權伺服器的執行和可用性。
動態租戶
您可能不希望每次新增新租戶時都重新啟動應用程式。在這種情況下,您可以為 JwtIssuerReactiveAuthenticationManagerResolver 配置一個 ReactiveAuthenticationManager 例項的儲存庫,您可以在執行時對其進行編輯。
-
Java
-
Kotlin
private Mono<ReactiveAuthenticationManager> addManager(
Map<String, ReactiveAuthenticationManager> authenticationManagers, String issuer) {
return Mono.fromCallable(() -> ReactiveJwtDecoders.fromIssuerLocation(issuer))
.subscribeOn(Schedulers.boundedElastic())
.map(JwtReactiveAuthenticationManager::new)
.doOnNext((authenticationManager) -> authenticationManager.put(issuer, authenticationManager));
}
// ...
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver =
new JwtIssuerReactiveAuthenticationManagerResolver(authenticationManagers::get);
http
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
)
.oauth2ResourceServer((oauth2) -> oauth2
.authenticationManagerResolver(authenticationManagerResolver)
);
private fun addManager(
authenticationManagers: MutableMap<String, ReactiveAuthenticationManager>, issuer: String): Mono<JwtReactiveAuthenticationManager> {
return Mono.fromCallable { ReactiveJwtDecoders.fromIssuerLocation(issuer) }
.subscribeOn(Schedulers.boundedElastic())
.map { jwtDecoder: ReactiveJwtDecoder -> JwtReactiveAuthenticationManager(jwtDecoder) }
.doOnNext { authenticationManager: JwtReactiveAuthenticationManager -> authenticationManagers[issuer] = authenticationManager }
}
// ...
var customAuthenticationManagerResolver = JwtIssuerReactiveAuthenticationManagerResolver(authenticationManagers::get)
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
oauth2ResourceServer {
authenticationManagerResolver = customAuthenticationManagerResolver
}
}
在這種情況下,您使用一種策略來構造 JwtIssuerReactiveAuthenticationManagerResolver,該策略根據頒發者獲取 ReactiveAuthenticationManager。這種方法允許我們在執行時從儲存庫(在前面的程式碼片段中顯示為 Map)中新增和刪除元素。
|
簡單地接受任何頒發者並從中構建 |