feat(新增): 用户认证
This commit is contained in:
parent
175e238852
commit
91bf18844a
|
@ -30,7 +30,7 @@ open class BaseContext {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLoginVo(): LoginVo? {
|
||||
fun getLoginVo(): LoginVo {
|
||||
return loginVo.get()
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,15 @@ import lombok.NoArgsConstructor
|
|||
@Schema(name = "EmailTemplateDto", title = "邮箱模板请求内容", description = "邮箱模板请求内容")
|
||||
class EmailTemplateDto {
|
||||
@Schema(name = "templateName", title = "模板名称")
|
||||
var templateName: @NotBlank(message = "模板名称不能为空") String? = null
|
||||
var templateName: String? = null
|
||||
|
||||
@Schema(name = "subject", title = "主题")
|
||||
var subject: @NotBlank(message = "主题不能为空") String? = null
|
||||
@NotBlank(message = "主题不能为空")
|
||||
var subject: String? = null
|
||||
|
||||
@Schema(name = "body", title = "邮件内容")
|
||||
var body: @NotBlank(message = "邮件内容不能为空") String? = null
|
||||
@NotBlank(message = "邮件内容不能为空")
|
||||
var body: String? = null
|
||||
|
||||
@Schema(name = "type", title = "邮件类型")
|
||||
var type: String? = null
|
||||
|
|
|
@ -18,19 +18,23 @@ import lombok.NoArgsConstructor
|
|||
@Schema(name = "EmailUsersDto", title = "邮箱用户发送基础内容", description = "邮箱用户发送基础内容")
|
||||
class EmailUsersDto {
|
||||
@Schema(name = "id", title = "主键")
|
||||
var id: @NotBlank(message = "id不能为空") Long? = null
|
||||
@NotBlank(message = "id不能为空")
|
||||
var id: Long? = null
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
var email: @NotBlank(message = "邮箱不能为空") String? = null
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
var email: String? = null
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
var password: @NotBlank(message = "密码不能为空") String? = null
|
||||
@NotBlank(message = "密码不能为空")
|
||||
var password: String? = null
|
||||
|
||||
@Schema(name = "host", title = "SMTP服务器")
|
||||
var host: String? = null
|
||||
|
||||
@Schema(name = "port", title = "端口号")
|
||||
var port: @NotNull(message = "端口号不能为空") Int? = null
|
||||
@NotNull(message = "端口号不能为空")
|
||||
var port: Int? = null
|
||||
|
||||
@Schema(name = "smtpAgreement", title = "邮箱协议")
|
||||
var smtpAgreement: Int? = null
|
||||
|
|
|
@ -13,6 +13,7 @@ enum class ResultCodeEnum(val code: Int, val message: String) {
|
|||
EMAIL_CODE_SEND_SUCCESS(200, "邮箱验证码已发送"),
|
||||
|
||||
// 验证错误 201
|
||||
LOGIN_AUTH(208, "请先登陆"),
|
||||
USERNAME_OR_PASSWORD_NOT_EMPTY(201, "用户名或密码不能为空"),
|
||||
EMAIL_CODE_NOT_EMPTY(201, "邮箱验证码不能为空"),
|
||||
EMAIL_CODE_EMPTY(201, "邮箱验证码过期或不存在"),
|
||||
|
@ -28,7 +29,6 @@ enum class ResultCodeEnum(val code: Int, val message: String) {
|
|||
EMAIL_USER_TEMPLATE_IS_EMPTY(206, "邮件模板为空"),
|
||||
|
||||
// 身份过期 208
|
||||
LOGIN_AUTH(208, "请先登陆"),
|
||||
AUTHENTICATION_EXPIRED(208, "身份验证过期"),
|
||||
|
||||
// 封禁 209
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cn.bunny.services.security.config
|
||||
|
||||
import cn.bunny.services.security.custom.CustomPasswordEncoder
|
||||
import cn.bunny.services.security.filter.NoTokenAuthenticationFilter
|
||||
import cn.bunny.services.security.filter.TokenAuthenticationFilter
|
||||
import cn.bunny.services.security.filter.TokenLoginFilterService
|
||||
import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler
|
||||
|
@ -75,6 +76,7 @@ class WebSecurityConfig {
|
|||
UsernamePasswordAuthenticationFilter::class.java
|
||||
)
|
||||
// 其它权限鉴权过滤器
|
||||
.addFilterAt(NoTokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter::class.java)
|
||||
.addFilterAt(TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter::class.java)
|
||||
// 自定义密码加密器和用户登录
|
||||
.passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package cn.bunny.services.security.filter
|
||||
|
||||
import cn.bunny.common.service.context.BaseContext
|
||||
import cn.bunny.common.service.utils.JwtHelper
|
||||
import cn.bunny.common.service.utils.ResponseUtil.Companion.out
|
||||
import cn.bunny.dao.pojo.constant.RedisUserConstant
|
||||
import cn.bunny.dao.pojo.result.Result
|
||||
import cn.bunny.dao.pojo.result.ResultCodeEnum
|
||||
import cn.bunny.dao.vo.user.LoginVo
|
||||
import jakarta.servlet.FilterChain
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.data.redis.core.RedisTemplate
|
||||
import org.springframework.web.filter.OncePerRequestFilter
|
||||
|
||||
class NoTokenAuthenticationFilter(private val redisTemplate: RedisTemplate<Any, Any?>) : OncePerRequestFilter() {
|
||||
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {
|
||||
// 判断是否有token
|
||||
val token = request.getHeader("token") ?: run {
|
||||
out(response, Result.error(ResultCodeEnum.LOGIN_AUTH))
|
||||
return@doFilterInternal
|
||||
}
|
||||
|
||||
// 判断token是否过期
|
||||
val expired = JwtHelper.isExpired(token)
|
||||
if (expired) {
|
||||
out(response, Result.error(ResultCodeEnum.AUTHENTICATION_EXPIRED))
|
||||
return
|
||||
}
|
||||
|
||||
// token存在查找Redis
|
||||
val username = JwtHelper.getUsername(token)!!
|
||||
val userId = JwtHelper.getUserId(token)!!
|
||||
val loginVo: LoginVo? = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username)) as LoginVo?
|
||||
|
||||
// 判断用户是否禁用
|
||||
if (loginVo?.status == 1.toByte()) {
|
||||
out(response, Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED))
|
||||
return
|
||||
}
|
||||
|
||||
// 设置用户信息
|
||||
BaseContext.setUsername(username)
|
||||
BaseContext.setUserId(userId)
|
||||
BaseContext.setLoginVo(loginVo!!)
|
||||
|
||||
// 执行下一个过滤器
|
||||
doFilter(request, response, filterChain)
|
||||
}
|
||||
}
|
|
@ -16,14 +16,6 @@ import java.util.function.Consumer
|
|||
class TokenAuthenticationFilter(private val redisTemplate: RedisTemplate<Any, Any?>) : OncePerRequestFilter() {
|
||||
@Throws(ServletException::class, IOException::class, BunnyException::class)
|
||||
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||
val token = request.getHeader("token")
|
||||
|
||||
// 判断是否有token,如果后面还有过滤器就这样写
|
||||
// if (token == null) {
|
||||
// doFilter(request, response, chain)
|
||||
// return
|
||||
// }
|
||||
|
||||
|
||||
// 自定义实现内容
|
||||
val authentication = getAuthentication(request)
|
||||
|
@ -31,6 +23,8 @@ class TokenAuthenticationFilter(private val redisTemplate: RedisTemplate<Any, An
|
|||
|
||||
chain.doFilter(request, response)
|
||||
}
|
||||
// 判断是否有token,如果后面还有过滤器就这样写
|
||||
|
||||
|
||||
/**
|
||||
* * 用户请求判断
|
||||
|
|
|
@ -36,8 +36,7 @@ class CustomUserDetailsServiceImpl : CustomUserDetailsService {
|
|||
val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username).or().eq(AdminUser::username, username)
|
||||
|
||||
// 根据邮箱查询用户名
|
||||
val user = userMapper.selectOne(queryWrapper)
|
||||
user ?: throw UsernameNotFoundException("用户不存在 ")
|
||||
val user = userMapper.selectOne(queryWrapper) ?: throw UsernameNotFoundException("用户不存在")
|
||||
|
||||
// 根据用户id查询当前用户所有角色
|
||||
val roleList: List<Role> = roleMapper.selectListByUserId(user.id!!)
|
||||
|
|
|
@ -95,7 +95,7 @@ internal class UserServiceImpl : ServiceImpl<UserMapper?, AdminUser?>(), UserSer
|
|||
* * 退出登录
|
||||
*/
|
||||
override fun logOut() {
|
||||
val loginVo = BaseContext.getLoginVo() ?: throw BunnyException(ResultCodeEnum.FAIL_REQUEST_NOT_AUTH)
|
||||
val loginVo = BaseContext.getLoginVo()
|
||||
redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(loginVo.username!!))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue