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 实战项目:

开发你的第一个应用程序

您需要在 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();
	}

}

然后启动你的应用程序。

测试

授权码

打开您的浏览器,在地址栏中输入:

http://localhost:8080/oauth2/authorize?client_id=messaging-client&response_type=code&scope=message.write&redirect_uri=http://127.0.0.1:8080/authorized

然后你会看到一个登录页面:

image

输入用户名密码进行登录,它们分别为:user/password,然后您会看到许可页面:

image

勾选复选框,然后点击 Submit Consent,再次进行登录,您会看到 404 页面,不必管它,只需观察地址栏,它是这样的:

http://127.0.0.1:8080/authorized?code=T3HKFxHnWtccWW7_5q4K5HE8p923kHGFEbg99I-EiXod6ZR8WvyARj425gNVZNcuf0e_44onYj6Hm06va4ldZzcxR4trPENYXUeU8UOCyAYN7QEAwTKDyKxylJ5zHwhM

然后打开 Postman,发送一个 POST 请求:

http://localhost:8080/oauth2/token?grant_type=authorization_code&code=T3HKFxHnWtccWW7_5q4K5HE8p923kHGFEbg99I-EiXod6ZR8WvyARj425gNVZNcuf0e_44onYj6Hm06va4ldZzcxR4trPENYXUeU8UOCyAYN7QEAwTKDyKxylJ5zHwhM&redirect_uri=http://127.0.0.1:8080/authorized

注意 code 的值就是上面地址栏中的 code 的值。

image

在 Authorization 中选择 Basic Auth,填入用户名和密码:messaging-client/secret,发送请求,你就能看到下面的结果:

image

客户端凭证

在 Postman 中新建一个 POST 请求,其 URI 为:

http://localhost:8080/oauth2/token?grant_type=client_credentials&scope=message.read

与授权码类似,在 Authorization 中,您需要提供客户端的用户名密码:messaging-client/secret

image

接着发送请求,得到下面的结果:

image

刷新令牌

与客户端凭证类似,你需要新建一个 POST 请求,URI 为:

http://localhost:8080/oauth2/token?grant_type=refresh_token

并在 Authorization 中输入客户端的用户名密码:messaging-client/secret

image

在 Body 中新增一个参数 refresh_token,并把授权码中获取到的 refresh_token 作为值填充进去:

image

发送请求,你就会得到跟授权码中一样的结果,但是 access_token 却是新的。

posted @   ZnPi  阅读(1756)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示