Spring Authorization Server 入门
如果您刚刚开始使用 Spring Authorization Server,下面的部分将引导您创建第一个应用程序。
概述
Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它构建在 Spring Security 之上,为构建OpenID Connect 1.0 身份认证和 OAuth2 授权服务器产品提供安全、轻量级和可定制的基础。
系统要求
Spring Authorization Server 需要 Java 8 或更高版本的运行时环境。
安装 Spring Authorization Server
Spring Authorization Server 可以在任何已经使用 Spring Security 的地方使用。
开始使用 Spring Authorization Server 最简单的方法是创建一个基于 Spring boot 的应用程序。然后将 Spring Authorization Server 添加为依赖项:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>0.3.1</version>
</dependency>
本文代码与项目实战
本文代码已托管至 Gitee:https://gitee.com/linjiabin100/spring-authorization-server-sample/tree/master/getting-started
Spring Authorization Server 实战项目:
Gitee | GitHub | |
---|---|---|
后端 | https://gitee.com/linjiabin100/pi-cloud.git | https://github.com/zengpi/pi-cloud.git |
前端 | https://gitee.com/linjiabin100/pi-cloud-web.git | https://github.com/zengpi/pi-cloud-web.git |
开发你的第一个应用程序
您需要在 Spring Boot 配置类中定义 Spring Authorization Server 所需组件。这些组件可以定义如下:
@Configuration
public class SecurityConfig {
/**
* Spring Security 过滤器链,用于配置协议端点
* @param http /
* @return /
* @throws Exception /
*/
@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();
}
/**
* Spring Security 过滤器链,用于身份验证
* @param http /
* @return /
* @throws Exception /
*/
@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();
}
/**
* UserDetailsService 实例,用于检索要进行身份验证的用户
* @return /
*/
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
/**
* RegisteredClientRepository 实例,用于管理客户端
* @return /
*/
@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")
.scope(OidcScopes.OPENID)
.scope("message.read")
.scope("message.write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
/**
* com.nimbusds.jose.jwk.source.JWKSource 实例,用于签署访问令牌
* @return /
*/
@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);
}
/**
* java.security.KeyPair 实例,加载 JWT 公钥和私钥
* @return /
*/
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;
}
/**
* (REQUIRED)包含OAuth2授权服务器的配置设置。它指定协议端点的URI以及 issuer 标识符。
* @return /
*/
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.builder().build();
}
}
然后启动你的应用程序。
测试
授权码
打开您的浏览器,在地址栏中输入:
然后你会看到一个登录页面:
输入用户名密码进行登录,它们分别为:user/password,然后您会看到许可页面:
勾选复选框,然后点击 Submit Consent,再次进行登录,您会看到 404 页面,不必管它,只需观察地址栏,它是这样的:
然后打开 Postman,发送一个 POST 请求:
注意 code 的值就是上面地址栏中的 code 的值。
在 Authorization 中选择 Basic Auth,填入用户名和密码:messaging-client/secret,发送请求,你就能看到下面的结果:
客户端凭证
在 Postman 中新建一个 POST 请求,其 URI 为:
http://localhost:8080/oauth2/token?grant_type=client_credentials&scope=message.read
与授权码类似,在 Authorization 中,您需要提供客户端的用户名密码:messaging-client/secret
接着发送请求,得到下面的结果:
刷新令牌
与客户端凭证类似,你需要新建一个 POST 请求,URI 为:
http://localhost:8080/oauth2/token?grant_type=refresh_token
并在 Authorization 中输入客户端的用户名密码:messaging-client/secret
在 Body 中新增一个参数 refresh_token,并把授权码中获取到的 refresh_token 作为值填充进去:
发送请求,你就会得到跟授权码中一样的结果,但是 access_token 却是新的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南