Spring Authorization Server (一)基本搭建

本文介绍了如何使用SpringAuthorizationServer搭建一个支持OAuth2.1和OpenIDConnect1.0规范的授权服务器。首先,创建Springboot2项目并添加相关依赖,然后配置SecurityConfig,包括设置安全过滤链、用户详情服务、客户端注册以及JWT解码。通过配置,实现了从登录、授权到重定向的流程,验证了项目的正确配置和启动。
摘要由CSDN通过智能技术生成

Spring Authorization Server (一)基本搭建

简介

Spring Authorization Server 是一个框架,它提供OAuth 2.1和OpenID Connect 1.0规范以及其他相关规范的实现。它建立在Spring Security之上,为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产品提供安全、轻量级和可定制的基础。

快速开始

新建一个Spring boot 2 版本的项目,添加以下依赖

0.4.1 版本不支持Spring boot 3 版本及以上版本,如果想使用Spring boot 3 版本及以上版本。修改 0.4.1 版本为 1.0.1 及以上版本

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<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>0.4.1</version>
</dependency>

创建 config 文件夹,在其中添加 SecurityConfig 配置类

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

@Configuration
public class SecurityConfig {

	@Bean
	@Order(1)
	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
			throws Exception {
		OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
		http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
		    // 开启 OpenID Connect 1.0 默认是关闭的
			.oidc(Customizer.withDefaults());	
		http
	        // 配置未从授权端点进行身份验证时重定向到登录页面
			.exceptionHandling((exceptions) -> exceptions
				.authenticationEntryPoint(
					new LoginUrlAuthenticationEntryPoint("/login"))
			)
			// 接受用户信息 客户端注册的访问令牌
			.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
		return http.build();
	}

	@Bean
	@Order(2)
	public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
			throws Exception {
	    // 开启Spring security 表单认证 并且配置所有请求都需要认证
		http
			.authorizeHttpRequests((authorize) -> authorize
				.anyRequest().authenticated()
			)
			.formLogin(Customizer.withDefaults());
		return http.build();
	}

	@Bean (3)
	public UserDetailsService userDetailsService() {
	    // 在内存中注册了一个账户
		UserDetails userDetails = User.withDefaultPasswordEncoder()
				.username("admin")
				.password("123456")
				.roles("admin")
				.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("https://www.baidu.com")
				.scope("message.read")
				.scope("message.write")
				.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
				.build();
		return new InMemoryRegisteredClientRepository(registeredClient);
	}

	@Bean
	public JWKSource<SecurityContext> jwkSource() {
	    // 生成 jwk
		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() {
	    // 生成 RSA 密钥
		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 JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
	    // jwk 解码
		return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
	}

	@Bean
	public AuthorizationServerSettings authorizationServerSettings() {
	    // 认证服务配置
		return AuthorizationServerSettings.builder().build();
	}

}

启动项目,验证是否配置成功。

在浏览器输入以下地址,请求一个 code 。

http://localhost:8080/oauth2/authorize?response_type=code&client_id=messaging-client&scope=message.read&redirect_uri=https://www.baidu.com

目前处于未登录的状态,会跳转到登录页面,输入配置的账户密码,会跳转到授权页面,点击授权,会跳转到 baidu 的页面。并且在 baidu 的域名地址后面会有一个 code 参数,此时说明我们的认证中心项目是正确配置并且启动成功了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Authorization Server 是一个基于 Spring Boot 构建的轻量级、可扩展且易于使用的 OAuth 2.0 授权服务器,它提供了一系列的组件来支持 OAuth 2.0 和 OpenID Connect 1.0 标准。在 Spring Authorization Server 中,JSON Web Token(JWT)是一个核心概念,因为它是 OAuth 2.0 和 OpenID Connect 1.0 标准中用于表示和传递安全凭证的标准化格式。 JWT 的核心用途是在请求和响应之间传递授权令牌(Access Token)和刷新令牌(Refresh Token)。在 Spring Authorization Server 中,JWT 是通过将 OAuth 2.0 和 OpenID Connect 1.0 标准中的一些属性打包成 JSON 格式的方式来生成的,这些属性包括:令牌类型、令牌签发者、令牌主题、过期时间、ID 等。通过 JWT,我们可以轻松地在不同的系统间传递安全凭证,同时也可以减轻认证和授权的负担。 除了 JWT,Spring Authorization Server 还支持多种授权与认证流程,例如 Authorization Code、Implicit、Resource Owner Credentials 和 Client Credentials 等。同时,它还提供了一些基本的功能,例如授权令牌和刷新令牌的生命周期管理、路由规则配置和用户管理等等,使得它可以作为一个完整的授权服务器来使用。 总之,Spring Authorization Server 是一个具有强大的功能和灵活的配置选项的授权服务器,能够支持多种认证和授权流程,并提供了方便的 JWT 生成和传递等功能。对于需要构建安全性强、可扩展、易于管理的 API 和微服务的开发者来说,它是一个值得考虑的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值