SAS-Spring-Boot-Authorization-Server
一、前言
文章较长,步骤比较繁琐,请各位读者耐心观看。 上篇文章大概了解了下框架的相关理论,本篇文章将带大家一步步构建一个简单的认证服务器 开始之前先放一下文档的链接:官网文档
二、项目环境要求(当前框架版本1.1.0)
- Spring Boot 版本大于等于3.1.0-RC1
- JDK版本大于等于17
三、认证项目搭建
1. 创建工程
1. 在Idea中或Spring Initializr中创建spring boot项目
Spring Boot版本选择3.1.0,Java版本选择17以上,在Dependencies中勾选Spring Authorization Server和spring web依赖,其它看自己需要
引入持久层框架(本人用的是MybatisPlus,读者可自选)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
引入webjars和bootstrap,自定义登录页和确认页面时使用
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.2.3</version>
</dependency>
项目pom.xml示例
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>authorization-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>authorization-example</name>
<description>authorization-example</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 初始化框架自带数据库表
schema位置如图
- org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql
- org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql
- org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql
- org/springframework/security/core/userdetails/jdbc/users.ddl
修改后适配MySQL的SQL如下
-- 用户授权确认表
CREATE TABLE oauth2_authorization_consent
(
registered_client_id varchar(100) NOT NULL,
principal_name varchar(200) NOT NULL,
authorities varchar(1000) NOT NULL,
PRIMARY KEY (registered_client_id, principal_name)
);
-- 用户认证信息表
CREATE TABLE oauth2_authorization
(
id varchar(100) NOT NULL,
registered_client_id varchar(100) NOT NULL,
principal_name varchar(200) NOT NULL,
authorization_grant_type varchar(100) NOT NULL,
authorized_scopes varchar(1000) DEFAULT NULL,
attributes blob DEFAULT NULL,
state varchar(500) DEFAULT NULL,
authorization_code_value blob DEFAULT NULL,
authorization_code_issued_at DATETIME DEFAULT NULL,
authorization_code_expires_at DATETIME DEFAULT NULL,
authorization_code_metadata blob DEFAULT NULL,
access_token_value blob DEFAULT NULL,
access_token_issued_at DATETIME DEFAULT NULL,
access_token_expires_at DATETIME DEFAULT NULL,
access_token_metadata blob DEFAULT NULL,
access_token_type varchar(100) DEFAULT NULL,
access_token_scopes varchar(1000) DEFAULT NULL,
oidc_id_token_value blob DEFAULT NULL,
oidc_id_token_issued_at DATETIME DEFAULT NULL,
oidc_id_token_expires_at DATETIME DEFAULT NULL,
oidc_id_token_metadata blob DEFAULT NULL,
refresh_token_value blob DEFAULT NULL,
refresh_token_issued_at DATETIME DEFAULT NULL,
refresh_token_expires_at DATETIME DEFAULT NULL,
refresh_token_metadata blob DEFAULT NULL,
user_code_value blob DEFAULT NULL,
user_code_issued_at DATETIME DEFAULT NULL,
user_code_expires_at DATETIME DEFAULT NULL,
user_code_metadata blob DEFAULT NULL,
device_code_value blob DEFAULT NULL,
device_code_issued_at DATETIME DEFAULT NULL,
device_code_expires_at DATETIME DEFAULT NULL,
device_code_metadata blob DEFAULT NULL,
PRIMARY KEY (id)
);
-- 客户端表
CREATE TABLE oauth2_registered_client
(
id varchar(100) NOT NULL,
client_id varchar(100) NOT NULL,
client_id_issued_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
client_secret varchar(200) DEFAULT NULL,
client_secret_expires_at DATETIME DEFAULT NULL,
client_name varchar(200) NOT NULL,
client_authentication_methods varchar(1000) NOT NULL,
authorization_grant_types varchar(1000) NOT NULL,
redirect_uris varchar(1000) DEFAULT NULL,
post_logout_redirect_uris varchar(1000) DEFAULT NULL,
scopes varchar(1000) NOT NULL,
client_settings varchar(2000) NOT NULL,
token_settings varchar(2000) NOT NULL,
PRIMARY KEY (id)
);
2. 在config包下创建AuthorizationConfig类,并添加配置
1. 配置端点的过滤器链
/**
* 配置端点的过滤器链
*
* @param http spring security核心配置类
* @return 过滤器链
* @throws Exception 抛出
*/
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
// 配置默认的设置,忽略认证端点的csrf校验
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
// 开启OpenID Connect 1.0协议相关端点
.oidc(Customizer.withDefaults())
// 设置自定义用户确认授权页
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI));
http
// 当未登录时访问认证端点时重定向至login页面
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// 处理使用access token访问用户信息端点和客户端注册端点
.oauth2ResourceServer((resourceServer) -> resourceServer
.jwt(Customizer.withDefaults()));
return http.build();
}