当前位置: 首页 > 知识库问答 >
问题:

Spring security UsernamePasswordAuthenticationToken总是返回403:用户凭据已过期

羊新翰
2023-03-14

我试图在我的kotlin应用程序中实现基于Spring security JWT的授权,但是在每次/authenticate(登录)时,UsernamePasswordAuthenticationToken在数据库中找到用户,但返回403:用户凭据已经过期,即使是刚刚添加的用户。

SecurityConfiguration类:

@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类

@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)
 }
}
@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)
    }
}
@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")
    }
}

共有1个答案

汝彭薄
2023-03-14

发现了问题,可能会帮助别人。在我的UserDetails服务中,我将方法硬编码为总是返回false的用户进行映射

  override fun isCredentialsNonExpired(): Boolean {
    return false
}
 类似资料:
  • 我与Laravel有一个项目,负责管理endpoint调用,并通过Vue控制前端。 当用户登录时,响应(令牌)保存在本地存储中,然后在app.js我将此令牌自动添加到所有调用中。 登录 应用程序。js 现在,我们将看到问题。 当我们转到第二页时,将自动启动endpoint调用以填充一些输入。此调用理论上具有本地存储令牌。 路由(APIendpoint) 头部控制器 这将返回拒绝访问。令牌在标头中被

  • 我编写了一些逻辑,将文件上传到Google Drive文件夹中,该文件夹共享给服务帐户(uploader@uploadproject-204816.iam.gserviceaccount.com) 谷歌驱动器本身与我的G Suite帐户相关联。 从那以后,上传不起作用,即使上传一个小文件也会出现这个错误。 使用我的真实帐户,我清理了服务帐户拥有的所有文件,甚至是那些“无组织”的文件。 左边的配额上

  • 我是Spring的新手,我一直在尝试使用Spring Security性实现一个简单的登录页面。但在提供登录凭据后,它总是转到拒绝访问的url。loadUserByUsername()方法总是在我提供正确的用户名和密码后返回一个用户。但我不知道如何找到用户对象返回后会发生什么。 用户只有一个角色。该方法返回具有超级用户角色的用户。 这是我的Spring Security配置类 这是我的UserDe

  • 在此处为客户端凭据流使用Spotify文档: 我能够在谷歌应用程序脚本(Javascript)中创建API请求。 我对两件事感到困惑,请能够回答这两件事。 1). Spotify文档声明在授权标头中的客户端凭据之前输入“Basic”。 然而,当我运行这段代码时,我得到了这个错误 如果我在使用客户端凭据流,为什么它认为我在使用承载令牌?(同样,如果我将身份验证更改为Bearer,我会收到401错误“

  • 问题内容: 结果始终为1: 我在phpMyAdmin中运行了$ sql查询,它返回3,所以查询不是问题。$ vote_total全局初始化为0,因此1来自某个地方。我还需要提供什么其他信息来帮助我? 谢谢,瑞安 问题答案: 返回选定的行数,而不是特定行的字段。使用来获取您与您的查询选择的行: 您还可以用来获取一行并获取特定字段: 这将获取第一行(从零开始)并返回第一字段(从零开始)。

  • 问题内容: 我已经写了这段简单的代码: 在我的情况当属。谁能建议/建议出什么问题了? 问题答案: 错误检查和处理是程序员的朋友。检查初始化和执行cURL函数的返回值。并在失败的情况下包含更多信息: *在 手动状态: 成功返回cURL句柄,错误返回 FALSE 。 我观察到该函数在您使用其参数且无法解析域时会返回。如果未使用该参数,则该函数 可能 永远不会返回。但是,请务必始终进行检查,因为该手册并