简体   繁体   English

Spring 安全 UsernamePasswordAuthenticationToken 始终返回 403:用户凭据已过期

[英]Spring security UsernamePasswordAuthenticationToken always returns 403: User credentials have expired

I'm trying to implement a Spring security JWT based authorization inside my kotlin app but on every /authenticate (login) the UsernamePasswordAuthenticationToken finds the user in database but returns 403: User credentials have expired, even for just added user.我正在尝试在我的 kotlin 应用程序中实现基于 Spring 安全 JWT 的授权,但是在每个 /authenticate(登录)上,即使返回 UsernamePassword3Token 的用户凭据也已过期,但 UsernamePassword3Token: 用户已找到用户凭据。

SecurityConfiguration class:安全配置 class:

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
class SecurityConfiguration(
private val userDetailsService: UserDetailService,
private val jwtAuthorizationFilter: JwtAuthorizationFilter,
) : WebSecurityConfigurerAdapter() {

@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
    http.cors().and()
        .csrf().disable()
         http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter::class.java)
        .authorizeRequests()
        .antMatchers("/api/public/**").permitAll()
        .antMatchers("/api/authenticate").permitAll()
        .anyRequest().authenticated()
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}

@Bean
@Throws(Exception::class)
override fun authenticationManagerBean(): AuthenticationManager {
    return super.authenticationManagerBean()
}

@Throws(Exception::class)
public override fun configure(auth: AuthenticationManagerBuilder) {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder())
}

@Bean
fun passwordEncoder() = BCryptPasswordEncoder()

@Bean
fun corsConfigurationSource(): CorsConfigurationSource {
    val source = UrlBasedCorsConfigurationSource()
    source.registerCorsConfiguration("/**", CorsConfiguration().applyPermitDefaultValues())
    return source
 }
}

AuthorizationFilter class授权过滤器 class

@Component
class JwtAuthorizationFilter(
private val jwtUtil: JtwUtil,
private val userDetailsService: UserDetailsService) : OncePerRequestFilter() {

@Throws(IOException::class, ServletException::class)
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse,
                              filterChain: FilterChain
) {
    val header = request.getHeader(SecurityConstants.TOKEN_HEADER)

    if (StringUtils.isEmpty(header) || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
        filterChain.doFilter(request, response)
        return
    }

    val jwt: String = header.substring(7)
    val username: String? = jwtUtil.extractUsername(jwt)

    if (username != null && SecurityContextHolder.getContext().authentication == null) {
        val userDetails: UserDetails = userDetailsService.loadUserByUsername(username)
        val isValidToken: Boolean = jwtUtil.validateToken(jwt, userDetails)
        if (isValidToken) {
            val usernamePasswordAuthenticationToken = 
    UsernamePasswordAuthenticationToken(userDetails, null, userDetails.authorities)
            usernamePasswordAuthenticationToken.details = 
    WebAuthenticationDetailsSource().buildDetails(request)
            SecurityContextHolder.getContext().authentication = 
    usernamePasswordAuthenticationToken
        }
    }

    filterChain.doFilter(request, response)
 }
}

UserDetailsService:用户详情服务:

@Service
class UserDetailService(private val userRepository: UserRepository): UserDetailsService {
override fun loadUserByUsername(username: String?): UserDetails? {
    try {
        val user: UserTable = userRepository.findByUsername(username)
            ?: throw UsernameNotFoundException("Username $username not found")
        return AppUserDetails(user)

    } catch (e: Exception) {
        throw Exception(e)
    }
}

This is the API I call to try and authorize user in database这是我调用的 API 尝试授权数据库中的用户

@RequestMapping("/api/authenticate")
@RestController
class AuthenticationController(
private val authenticationManager: AuthenticationManager,
private val userDetailsService: UserDetailsService,
private val userDetailService: UserDetailService,
private val jwtUtil: JtwUtil
) {

@PostMapping
fun authenticateUser(@RequestBody authenticationRequest: AuthenticationRequest): 
 ResponseEntity<AuthenticationResponse> {
    try {
        
 authenticationManager.authenticate
 (UsernamePasswordAuthenticationToken(authenticationRequest.username, 
 authenticationRequest.password))

        val userDetails: UserDetails = 
 userDetailsService.loadUserByUsername(authenticationRequest.username)
        val jwt: String = jwtUtil.generateToken(userDetails)

        return ResponseEntity.ok(AuthenticationResponse(jwt))
    } catch (e: BadCredentialsException) {
        throw BadCredentialsException("Incorrect username or password $e")
    }
}

I've debugged the request and found that the authentication fails on this method:我调试了请求,发现此方法的身份验证失败:
AbstractUserDetailsAuthenticationProvider

错误

Found the issue, might help someone else.发现问题,可能对其他人有帮助。 In my UserDetails service where I map the User I've hardcoded the method to always returns false在我的 UserDetails 服务中,我在 map 的用户中硬编码了该方法以始终返回 false

  override fun isCredentialsNonExpired(): Boolean {
    return false
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 安全总是返回 HTTP 403 - Spring security always returns HTTP 403 春季安全性:AnonymousAuthenticationToken与UsernamePasswordAuthenticationToken - Spring Security: AnonymousAuthenticationToken vs UsernamePasswordAuthenticationToken Spring 安全 JWT 验证不使用 UsernamePasswordAuthenticationToken - Spring Security JWT validation without using UsernamePasswordAuthenticationToken 无法配置 spring boot 安全 - 总是 403 - Cannot configure spring boot security - always 403 angularjs中的Spring Security返回禁止登录的403 - Spring security in angularjs returns 403 forbidden for login 为什么 permitAll() 返回 403 spring security? - Why permitAll() returns 403 spring security? Spring Security UsernamePasswordAuthenticationToken在调用超类方法之前抛出异常 - Spring Security UsernamePasswordAuthenticationToken throws Exception before invoking super class method Spring Security + LDAP始终返回BadCredentialsException - Spring Security + LDAP always returns BadCredentialsException Zkoss Spring Security始终返回AnonymousAuthenticationToken - Zkoss Spring Security always returns AnonymousAuthenticationToken Spring security 5/spring boot 2.2: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken - Spring security 5/spring boot 2.2: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM