优化验证方式
This commit is contained in:
parent
d36e6379c0
commit
a8f8fa97d7
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user