Spring Boot
Java
Spring Boot
2022-02-15 10:02
阅读:64
评论:0
spring-security封装权限认证自动配置,开箱即用
spring-security-auth-starter spring-security 权限认证自动配置,开箱即用,支持动态续租token过期时间,支持统一API服务接口调用权限认证,支持基于@PreAuthorize注解方式授权认证,支持基于URL路径权限认证。登录接口前端可对密码进行rsa加密...
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-a5d25dd831.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mobile/css/edit_views_md-250d69367f.min.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/style-e504d6a974.css">
<h2><a id="springsecurityauthstarter_0"></a>spring-security-auth-starter</h2>
spring-security 权限认证自动配置,开箱即用,支持动态续租token过期时间,支持统一API服务接口调用权限认证,支持基于
@PreAuthorize注解方式授权认证,支持基于URL路径权限认证。登录接口前端可对密码进行rsa加密(前端公钥加密,后端私钥解密),支持自定义登录接口(微信公众授权/小程序授权可选自定义登录接口)
开源地址
application.yml配置
security:
config:
# 是否启用跨域请求配置
enableCors: false
# token 请求头名称
header: Authorization
# 令牌前缀
token-start-with: TestBearer
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
# token-validity-in-seconds: 60000
token-validity-in-seconds: 14400000
# 验证码 key(配置key意味着对验证码进行校验)
# 使用方式:
# 配置验证缓存前缀key即为 codeKey
# 生成验证码并生成唯一值例如 uuid 并且 codeKey+uuid 作为redis key缓存验证码
# uuid发送给客户端,客户端提交请求携带验证码以及uuid
# code-key: code-key
# 是否踢掉之前已经登录的token
single-login: false
# 匿名访问url
ignoring-urls:
- /api/ignoringUrls
- /redissonTest/**
# token校验访问url
auth-urls-prefix:
- /auto/demo
# 密码加密的私钥, 密码加密传输,前端公钥加密,后端私钥解密
# rsa-private-key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
# 指定des加密密码。登录成功后,token也会跟随用户信息缓存起来,经过des加密,
des-password: 12345678
# 启动系统后是否删除登录过的token
app-run-delete-history-token: false
# 配置用户密码加密方式
id-for-encode: bcrypt
# 权限认证方式,CODE或URL,不管使用哪种方式调调用fetchRolePermissionInfo方法查询权限
# com.gitee.osinn.boot.securityjwt.service.ISecurityService.fetchRolePermissionInfo()
# 如果是URL方式调用fetchResourcePermissionAll()方法查询资源路径(UIR)以及资源路径权限编码
auth-type: CODE
# 前端传服务名称之属性名称
service-name: service
# 前端传服务接口方法名称之属性名称
service-handler-method: methodName
# 如果是api服务层,前端需要传参数:接口方法名称
# 如果设置为true,需要service-handler-method 指定前端要调用的方法的参数名称
# 这时前端不只是传serviceName 需要调用的服务,还要传 serviceHandlerMethod具体要调用服务下的哪个接口方法
api-service: true
# 是否需要动态续租token过期时间
dynamic-refresh-token: true
...
使用方式
- 在启动类上添加
@EnableSecurityJwt注解启用自动配置 - 在启动类上添加
@DisableSecurityJwt注解禁用Spring security自动配置
如果在项目中引入此依赖,不想用内置的加密方法式,可以自行注入自定义加密,注入方式如下
@Bean
public PasswordEncoder passwordEncoder() {
// CustomizePasswordEncoder则是自定义密码加密方式类
// CustomizePasswordEncoder.class可以参考 com.gitee.osinn.boot.securityjwt.security.crypto.Md5Sha512PasswordEncoder
return new CustomizePasswordEncoder();
}
新增用户密码加密
// 新增一个账号
userEntity = new SysUserEntity();
userEntity.setAccount("demo");
userEntity.setNickname("演示");
userEntity.setStatus(StatusEnum.ENABLE);
// idForEncode为配置用户密码加密方式
PasswordEncoder passwordEncoder = PasswordEncoderUtils.getPasswordEncoder(idForEncode);
userEntity.setPassword(passwordEncoder.encode("12345600")); // 密码加密
sysUserMapper.insert(userEntity);
图形验证码
- 使用内置实现图形验证码,引入依赖
<!-- 图形验证码依赖包 -->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>${easy-captcha.version}</version>
</dependency>
自定义图形验证码
实现 ISecurityCaptchaCodeService 接口里面的方法即可
权限认证方式
- 在配置文件中如果不将
security.config.auth-type指定为URL,那么使用security默认的@PreAuthorize注解方式路径授权,例如:@PreAuthorize("hasAuthority('system:sysMenu:details')") - 默认为
URL,即为基于url路径授权 SERVICE方式结合@API注解使用,用于通过服务名称来请求业务接口
关于@API注解
/** * 服务API注解,在类上添加此注解 * <p> * 有时候我们调用的接口是通过注解指定服务名称 * 前端通过指定服务名称调用接口 * </p> * * @author wency_cai **/ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Component public @interface API {/** * 服务名称-应用场景:用于通过服务名称调用接口指定的服务名称 * * @return 服务名称 */ String service(); /** * 是否需要认证登录 * * @return true 需要认证登录,false 不需要认证登录 */ boolean needLogin() default false; /** * 接口拥有的权限 * * @return 权限code */ String permission() default ""; /** * 是否需要权限认证 * * @return true 需要认证权限,false 不需要认证权限 */ boolean needPermission() default false;
}
IOnlineUserService接口
- 在需要的地方直接注入
@Autowired
private IOnlineUserService onlineUserService;
- 接口具有的方法
/** * 登录认证 * * @param authUser * @param request * @return */ JwtUser auth(AuthUser authUser, HttpServletRequest request);/** * 退出登录删除token * * @throws SecurityJwtException 请求头不携带token抛出异常 */ void logout() throws SecurityJwtException; /** * 根据用户id筛选在线的用户(多端登录,多个token对应一个用户) * * @param filterUserId * @return */ List<OnlineUser> fetchOnlineUserAllByUserId(String filterUserId); /** * 获取当前在线用户 * * @return */ OnlineUser fetchOnlineUserCompleteInfo(); /** * 根据token获取当前在线用户 * * @return */ OnlineUser fetchOnlineUserCompleteInfoByToken(String token); /** * 根据指定的key查询在线用户 * * @param key * @return */ OnlineUser getOne(String key); /** * 根据前缀删除缓存 * * @param prefixKey */ void deleteCacheByPrefix(String prefixKey); /** * 删除所有缓存 */ void deleteCacheAll(); /** * 获取全部在线用户 * * @return */ List<OnlineUser> fetchOnlineUserAll(); /** * 刷新token缓存过期时间 */ void refreshToken(); /** * 根据用户ID删除token * * @param ids 用户id */ void editUserInfoForciblyLogout(List<Object> ids);