优化验证方式

This commit is contained in:
05412 2024-07-25 18:14:04 +08:00
parent d36e6379c0
commit a8f8fa97d7

View File

@ -1,100 +0,0 @@
package dev.surl.surl.filter
import com.fasterxml.jackson.databind.ObjectMapper
import dev.surl.surl.common.Msg
import dev.surl.surl.common.enums.RedisStorage
import dev.surl.surl.dto.UserDto
import dev.surl.surl.service.UserService
import dev.surl.surl.util.JwtTokenUtil
import dev.surl.surl.util.redis.RedisUtil
import dev.surl.surl.util.validate
import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import jakarta.validation.ConstraintViolationException
import jakarta.validation.Validator
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.stereotype.Component
import java.nio.charset.StandardCharsets
/**
* 登录过滤器
*/
@Component
class UsernamePasswordAuthenticationCheckFilter(
private val om: ObjectMapper,
private val validator: Validator,
private val jwtTokenUtil: JwtTokenUtil,
private val userService: UserService,
private val redisUtil: RedisUtil
) : UsernamePasswordAuthenticationFilter() {
init {
// 设置登录地址
setFilterProcessesUrl("/login")
authenticationManager = AuthenticationManager { it }
}
/**
* 尝试登录
*/
override fun attemptAuthentication(request: HttpServletRequest?, response: HttpServletResponse?): Authentication {
request ?: throw IllegalArgumentException("request is null")
val body = String(request.inputStream.readAllBytes(), StandardCharsets.UTF_8)
val userDto = try {
om.readValue(body, UserDto::class.java)
} catch (e: Exception) {
throw object : AuthenticationException("request body is invalid", e) {}
}
// 尝试验证登录信息
try {
validate(userDto, validator)
} catch (e: ConstraintViolationException) {
throw object : AuthenticationException(e.constraintViolations.joinToString(";") { it.message }) {}
} catch (e: Exception) {
throw object : AuthenticationException(e.message) {}
}
if (!userService.authUser(userDto)) throw object : AuthenticationException("auth faild") {}
return authenticationManager.authenticate(
UsernamePasswordAuthenticationToken(
userDto.username, userDto.password, mutableListOf()
)
)
}
/**
* 登录成功生成并返回token
*/
override fun successfulAuthentication(
request: HttpServletRequest?, response: HttpServletResponse?, chain: FilterChain?, authResult: Authentication?
) {
val (expireAt, token) = jwtTokenUtil.getToken(authResult!!.name, authResult.authorities.map { it.authority })
redisUtil.setString(authResult.name, token, RedisStorage.TOKEN)
val responseBody = om.writeValueAsString(
Msg(
code = 0, value = mapOf("expireAt" to expireAt, "token" to token)
)
)
response?.run {
writer.write(responseBody)
writer.flush()
}
}
/**
* 登录失败 返回错误信息
*/
override fun unsuccessfulAuthentication(
request: HttpServletRequest?, response: HttpServletResponse?, failed: AuthenticationException?
) {
response?.run {
status = HttpServletResponse.SC_UNAUTHORIZED
writer.write(om.writeValueAsString(Msg<String>(code = -1, msg = failed?.message)))
writer.flush()
}
}
}