【问题标题】:Spring boot custom JWT filter not allowing any request without tokenSpring Boot 自定义 JWT 过滤器不允许任何没有令牌的请求
【发布时间】:2021-03-30 23:54:46
【问题描述】:

我正在使用带有 Spring Boot 安全配置的自定义 JWT 过滤器来允许某些没有 JWT 令牌的 API 请求。但是 WebSecurity 配置中的 permitAll() 方法不起作用(不允许任何没有 JWT 的请求)。它会引发自定义 InvalidJwtException。我在这里缺少什么?我已经尝试了很多谷歌搜索,但没有成功。

WebSecurityConfig 类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebSecurityConfig(
    private val jwtTokenProvider: JwtTokenProvider,
    private val filterChainExceptionHandler: FilterChainExceptionHandler,
) : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity?) {

        http?.csrf()?.disable()
        http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

        http
            ?.authorizeRequests()
            ?.antMatchers("/api/v1/auth/signin")?.permitAll()
            ?.antMatchers("/api/v1/auth/checkEmailExist")?.permitAll()
            ?.anyRequest()?.authenticated()

        http
            ?.addFilterBefore(JwtTokenFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter::class.java)
            ?.addFilterBefore(filterChainExceptionHandler, JwtTokenFilter::class.java)

    }

    @Bean
    fun passwordEncoder(): PasswordEncoder {
        return BCryptPasswordEncoder(10)
    }

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

JwtTokenFilter 类

@Component
class JwtTokenFilter(
    private val jwtTokenProvider: JwtTokenProvider
) : OncePerRequestFilter() {

    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        try {
            val token = jwtTokenProvider.resolveToken(request)
            if (token != null && jwtTokenProvider.validateToken(token)) {
                val auth = jwtTokenProvider.getAuthentication(token)
                SecurityContextHolder.getContext().authentication = auth
            }
        } catch (e: InvalidJwtException) {
            SecurityContextHolder.clearContext()
            throw InvalidJwtException(e.message, e.httpStatus)
        }
        filterChain.doFilter(request, response)
    }
}

解析令牌函数


 fun resolveToken(req: HttpServletRequest): String? {
        val bearerToken = req.getHeader(AUTHORIZATION_HEADER)
        return if (bearerToken != null && bearerToken.startsWith(BEARER)) {
            bearerToken.substring(7)
        } else {
            throw InvalidJwtException("Authorization token must be Bearer [token]", HttpStatus.FORBIDDEN)
        }
 }

【问题讨论】:

  • 那是你自己的代码在做的事情,没有token的时候,抛出异常。因为这总是在任何规则检查之前执行,所以它总是会抛出这个异常。因此不要抛出异常。
  • 这行不应该允许没有令牌的两个请求吗?因为它有 permitAll ()antMatchers("/api/v1/auth/signin")?.permitAll() antMatchers("/api/v1/auth/checkEmailExist")?.permitAll()
  • 没有。无论它是谁,它总是可以访问。但是,确定谁需要身份验证并在评估 permitAll 之前调用。如果您想禁用所有过滤器(不推荐),请将网络安全配置为 ignore 某些 URL然而,这会禁用该 URL 的所有安全过滤器。

标签: java spring spring-boot kotlin jwt


【解决方案1】:

您的令牌验证应排除身份验证 URL:

if (!request.getRequestURL().toString().contains("auth") || (token != null && jwtTokenProvider.validateToken(token))) 

您可以选择比我使用过的“auth”更好的字符串来识别排除的路径

【讨论】:

    猜你喜欢
    • 2021-08-27
    • 2020-08-11
    • 2018-08-19
    • 1970-01-01
    • 2023-02-25
    • 1970-01-01
    • 2020-01-04
    • 2019-07-20
    • 2022-11-15
    相关资源
    最近更新 更多