# cerberus-spring-boot-starter
**Repository Path**: ITEater/cerberus-spring-boot-starter
## Basic Information
- **Project Name**: cerberus-spring-boot-starter
- **Description**: 安全组件类,后续的安全框架与一些安全操作都由此框架来完成
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 1
- **Created**: 2018-05-20
- **Last Updated**: 2025-11-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一个高度配置化的spring-boot-security框架扩展
写SQL老是拼写错误?试试去SQL化的查询方式[https://gitee.com/ITEater/ameba-spring-boot-starter](https://gitee.com/ITEater/ameba-spring-boot-starter)
## 前言
1. 基于``spring-boot-starter-security``进行的安全配置扩展,主要基于**前后端分离**开发模式进行的封装并进行高度的配置化,主要包含**基本form表单配置,自定义登录配置、captcha配置、csrf配置、session配置、redis相关配置(session、token)、权限配置、登出配置**等
## 系统需求
  
## 当前版本

## 最快上手
### 项目引入
- 将此项目引入IDE,进行``mvn install``,在其他项目中引入,目前我在尝试引入到中央仓库,后续就不需要在进行导入了,直接使用即可
```xml
top.codef
cerberus-spring-boot-starter
0.7.1
```
### 最快上手
1. 在``application.yml``中,做如下配置:
```yml
cerberus:
form-login:
enabled: true
login-path: /login
param-pwd: pwd
param-username: username
fail-status: unauthorized
change-csrf-token-on-login-success: false
```
2. 创建一个``UserDetailsService``的实现类
```java
import java.util.List;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
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.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService implements UserDetailsService, InitializingBean {
@Autowired
private PasswordEncoder passwordEncoder;
private UserDetails user;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (user.getUsername().equals(username)) {
return user;
}
return null;
}
@Override
public void afterPropertiesSet() throws Exception {
user = User.builder().password(passwordEncoder.encode("123456")).username("admin").authorities(List.of())
.build();
}
}
```
3. 这样,一个登录就做好了结构就做好了,所以这里写一个接口调用

这样一个登录就完成了
### 模块介绍
目前整个的架构内大部分的功能都能就行配置化,接下来就一一进行介绍:
#### 登录配置
```yml
cerberus:
form-login:
enabled: true
login-path: /login
param-pwd: pwd
param-username: username
fail-status: unauthorized
change-csrf-token-on-login-success: false
```
|名称|类型|说明|必填|
|-|-|-| - |
|enabled|boolean|开启form表单登录| 是 |
|login-path|string|请求路径|是|
|param-pwd|string|密码参数名(password)|否|
|param-username|string|用户名参数名(username)|否|
|fail-tatus|enum|登录失败的http状态(默认401)|否|
|change-csrf-token-on-login-success|boolean|登录成功后是否换csrf-token(默认false)|否|
#### 安全异常状态码定义
- 安全异常主要包含:csrftoken验证异常,csrftoken缺失异常,未授权异常,以及拒绝访问异常,这些异常返回的异常状态码可以通过
#### 登录返回配置
- 登录成功或者失败会有对应的默认返回值(返回状态码,信息,信息状态码)
```yml
cerberus:
secure:
login-return:
failed-http-status: ok
failed-message: 登录失败
failed-message-status: 0
success-http-status: ok
success-message: 登录成功
success-message-status: 1
```
#### csrf配置
```yml
cerberus:
secure:
csrf:
csrf-header-name: x-token
csrf-session-attr-name: CSRF_TOKEN
enabled: true
ignoring-path-matchers:
- /login
```
|名称|类型|说明|必填|
|-|-|-| - |
|enabled|boolean|开启csrf验证| 是 |
|csrf-header-name|string|请求头中需要带的csrftoken验证名(默认:x-token)|否|
|csrf-session-attr-name|string|session中存储的csrfToken名(默认:CSRF.TOKEN)|否|
|ignoring-path-matchers|array|不需要csrf验证的请求|否|
- 需要说明的是,在前后端分离模式开发,登录成功后,response header 中会带上csrftoken(x-token),后续web终端的所有的请求就需要在request header中带上``x-token``对应参数:

#### session配置
```yml
cerberus:
secure:
session:
enabled: true
enable-redis-session-storage: true
invalidate-session-handle: auth-failed
invalidate-session-redirect-url:
max-session: 2
session-creation-policy: if-required
```
|名称|类型|说明|必填|
|-|-|-| - |
|enabled|boolean|开启session验证| 是 |
|enable-redis-session-storage|boolean|是否开启session的redis存储|否|
|invalidate-session-handle|enum|session验证失败处理(auth-failed<默认>,forbidden,no-handle,redirect)|否|
|invalidate-session-redirect-url|string|假如session验证不通过处理为redirect,redirect的路径(默认为"/")|否|
|max-session|int|用户验证最大支持session数量|是|
|session-creation-policy|enum|session创建规则(ALWAYS<默认> , NEVER ,IF_REQUIRED,STATELESS)|否|
- 这里的session配置通常指的是B/S项目中,验证用户时需要存到session中,用户登登录验证成功后``authentication``会通过``SecurityContextRepository``储存起来,默认情况下,``SecurityContextRepository``的实现bean就是``HttpSessionSecurityContextRepository``。
#### 自定义登录CustomLogin
- 其实springsecurity提供的form-login的方式实际上有很大限制,当然也可以使用spring security提供的其他的验证方式(basic、bigest、oauth2、openid、jwt等),我这里是将spring提供的formlogin方式进行了重写,重新定义了form登录功能,新登录可以实现但不限于
1. 最原始的表单登录
2. 多用户类型登录
3. 多租户登录
4. 验证码登录
5. 扫码登录
- 具体登录配置如下:
```yml
cerberus:
secure:
custom-login:
enabled: true
login-path: /login
option-param: optional
restful: true
params:
basic:
principal-param: username
credential-param: pwd
code:
principal-param: phone
credential-param: code
header-param-keys:
- tenant-id
```
|名称|类型|说明|必填|
|-|-|-| - |
|enabled|boolean|开启自定义登录|是|
|login-path|string|登录路径(默认/login)|否|
|option-param|string|登录模式参数名,(默认为optional)|否|
|restful|boolean|是否是restful风格登录(默认true)|否|
|params|map|登录模式中使用的参数信息,键表示对应的值|是|
|登录参数设置|
|principal-param|string|验证用户名参数|是|
|credential-param|string|验证用户资质参数|是|
|header-param-keys|list|额外需要的header参数|否|
- 除了以上配置,跟``UserDetailsService``类型,需要实现``CerberusUserDetailsService``,还需要实现验证接口``CerberusAuthenticationChecker``
```java
import java.util.List;
import java.util.Map;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import top.codef.secure.login.interfaces.CerberusUserDetailsService;
@Service
public class CustomUserService implements CerberusUserDetailsService {
// 表示支持的optional参数
private static final List NAMES = List.of("code", "basic");
@Override
public List names() {
return NAMES;
}
@Override
public UserDetails loadUserByUsername(String username, Map map) throws UsernameNotFoundException {
//your own getUser
return null;
}
}
```
- ``CerberusAuthenticationChecker``主要是获取到的用户信息进行用户验证
```java
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import top.codef.secure.login.CerberusAuthenticationToken;
import top.codef.secure.login.interfaces.CerberusAuthenticationChecker;
@Component
public class CustomUserChecker implements CerberusAuthenticationChecker {
private List NAMES = List.of("code");
// 通过redis实现code存取
private Map codeMap = new HashMap<>();
@Override
public List names() {
return NAMES;
}
@Override
public boolean check(UserDetails userDetails, CerberusAuthenticationToken authentication) {
var code = codeMap.get(userDetails.getUsername());
var verifyCode = (String) authentication.getCredentials();
return code != null && code.equals(verifyCode);
}
}
```
#### Captcha配置
- 配置如下:
```yml
cerberus:
secure:
captcha:
captcha-uris:
- /login
- /regist
enabled: true
```
|名称|类型|说明|必填|
|-|-|-| - |
|enabled|boolean|开启人机验证|是|
|captcha-uris|list|需要人机验证的请求路径|是|
- 这块的配置只是加了一个壳,并没有Captcha的实现,原因是市面上有众多的Captcha验证,具体实现是根据现实需要而定的。
- 除了通过配置开启captcha,还需要实现``CaptchaRepository``接口接入验证
```java
public interface CaptchaRepository {
/**
* 验证 captcha是否通过
*
* @param request
* @return
*/
public boolean check(HttpServletRequest request);
/**
* 清除现有已通过验证
*
* @param authentication
*/
public void clear(Authentication authentication);
}
```
### 总结
本框架实际上还有一些功能还没有介绍,后续会将文档持续更新。