# 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)、权限配置、登出配置**等 ## 系统需求 ![jdk版本](https://img.shields.io/badge/java-17%2B-red.svg?style=for-the-badge&logo=appveyor) ![maven版本](https://img.shields.io/badge/maven-3.2.5%2B-red.svg?style=for-the-badge&logo=appveyor) ![spring boot](https://img.shields.io/badge/spring%20boot-3.0.0%2B-red.svg?style=for-the-badge&logo=appveyor) ## 当前版本 ![目前工程版本](https://img.shields.io/badge/version-0.7.1-green.svg?style=for-the-badge&logo=appveyor) ## 最快上手 ### 项目引入 - 将此项目引入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. 这样,一个登录就做好了结构就做好了,所以这里写一个接口调用 ![10-1PNG.PNG](https://resources.codef.top/cerberus/pic/10-1PNG.PNG) 这样一个登录就完成了 ### 模块介绍 目前整个的架构内大部分的功能都能就行配置化,接下来就一一进行介绍: #### 登录配置 ```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``对应参数: ![10-2.PNG](https://resources.codef.top/cerberus/pic/10-2.PNG) #### 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); } ``` ### 总结 本框架实际上还有一些功能还没有介绍,后续会将文档持续更新。