Spring Authorization Server
簡介
官方主頁:https://spring.io/projects/spring-authorization-server
Spring Authorization Server
是一個框架,提供了 OAuth 2.1 和 OpenID Connect 1.0 規(guī)范以及其他相關(guān)規(guī)范的實現(xiàn)。 它建立在 Spring Security 之上,為構(gòu)建 OpenID Connect 1.0 Identity Providers 和 OAuth2 Authorization Server 產(chǎn)品提供安全、輕量級和可定制的基礎(chǔ)。
Spring實現(xiàn)OAuth2的舊版的框架是 Spring Security OAuth2
,該框架已停止維護。Spring Security OAuth2認(rèn)證/授權(quán)服務(wù)器的前世今生
功能列表
https://docs.spring.io/spring-authorization-server/docs/0.3.1/reference/html/overview.html
- 授權(quán)方式支持授權(quán)碼(Authorization Code)、客戶憑證(Client Credentials)
- 令牌支持刷新(Refresh Token)
- 令牌格式支持自包含(JWT)和引用(Opaque)
- …
入門案例
官方案例:https://docs.spring.io/spring-authorization-server/docs/0.3.1/reference/html/getting-started.html
本案例基于官方案例,做了一絲絲改動,便于調(diào)試。
1. 創(chuàng)建 SpringBoot 項目
一個 pom,一個 Application 啟動類,相信難不倒你,跳過。
2. 引入依賴
本案例使用 0.3.1
版本
<properties>
<spring-authorization-server.version>0.3.1</spring-authorization-server.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>${spring-authorization-server.version}</version>
</dependency>
</dependencies>
3. 編寫配置
-
配置類
為了便于調(diào)試授權(quán)碼流程,給客戶端多加了個重定向地址.redirectUri("https://cn.bing.com")
@Configuration
public class SecurityConfiguration {
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(
new LoginUrlAuthenticationEntryPoint("/login"))
);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin(Customizer.withDefaults());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
.redirectUri("http://127.0.0.1:8080/authorized")
.redirectUri("https://cn.bing.com") // 便于調(diào)試授權(quán)碼流程
.scope(OidcScopes.OPENID)
.scope("message.read")
.scope("message.write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
@Bean
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.builder().build();
}
}
-
application.yml
服務(wù)端口為9000
框架的異常信息不是很友好,此處增加了兩個類的 trace 日志,便于定位問題。
server:
port: 9000
logging:
level:
root: info
# org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: trace
# org.springframework.security: debug
org.springframework.security.web.FilterChainProxy: trace # 過濾器執(zhí)行順序
org.springframework.security.web.access.ExceptionTranslationFilter: trace #異常處理
4. 啟動
運行 啟動類
5. 測試
授權(quán)碼 獲取令牌
1. 三方應(yīng)用訪問授權(quán)頁
http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=message.read&redirect_uri=https://cn.bing.com
1.1 若用戶未登錄,則會重定向登錄頁
輸入配置類中的指定的用戶信息 user、password,登錄,登錄成功后會重定向到授權(quán)頁
1.2. 授權(quán)頁
2. 用戶授權(quán)
勾選授權(quán)作用域scope(即message.read),點擊 Submit Consent 允許授權(quán)
3. 獲取code
授權(quán)成功后,會重定向到上述地址并攜帶 code
值
4. 通過 code 獲取令牌
使用postman發(fā)送請求 POST /oauth2/token
,需要注意的是客戶端的信息以 Basic
方式認(rèn)證
填入上步驟獲取的 code
值
發(fā)送請求,得到響應(yīng),access_token
即為令牌。
刷新令牌
同樣是 POST /oauth2/token
接口,僅參數(shù)不同,客戶端的信息同樣以 Basic
方式認(rèn)證
使用上步驟獲取的 refresh_token
測試。
客戶端憑證 獲取令牌
同樣是 POST /oauth2/token
接口,僅參數(shù)不同,客戶端的信息同樣以 Basic
方式認(rèn)證
end文章來源:http://www.zghlxwxcb.cn/news/detail-569811.html
后續(xù)會繼續(xù)深挖框架的各種配置和功能,有興趣可以訂閱一下,會持續(xù)更新文章來源地址http://www.zghlxwxcb.cn/news/detail-569811.html
到了這里,關(guān)于【Spring Authorization Server 系列】(一)入門篇,快速搭建一個授權(quán)服務(wù)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!