【发布时间】: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