Я использую собственный фильтр JWT с настройкой безопасности весенней загрузки, чтобы разрешить определенные запросы API без токена JWT. Но метод allowAll() в конфигурации WebSecurity не работает (не разрешает никаких запросов без JWT). Он выдает пользовательское исключение InvalidJwtException. Что мне здесь не хватает? Я пробовал много поиска в Google, но не добился успеха.
Класс 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)
}
}
Функция ResolveToken
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)
}
}
Разве эти строки не должны разрешать оба запроса без токена? поскольку он имеет PermitAll () antMatchers ("/api/v1/auth/signin")?.permitAll() antMatchers ("/api/v1/auth/checkEmailExist")?.permitAll()
Нет. Доступ к нему всегда вне зависимости от того, кто это. Однако определить, кто требует аутентификации и что вызывается, прежде чем оценивается permitAll. Если вы хотите отключить все фильтры (не рекомендуется), настройте веб-безопасность на ignore определенные URL-адреса, однако это отключит все фильтры безопасности для этого URL-адреса.
Проверка вашего токена должна исключать URL-адреса аутентификации:
if (!request.getRequestURL().toString().contains("auth") || (token != null && jwtTokenProvider.validateToken(token)))
Вы можете выбрать лучшую строку для определения исключенных путей, чем «auth», которую я использовал.
Это то, что делает ваш собственный код, когда нет токена, выдает исключение. Поскольку это всегда выполняется перед проверкой любого правила, оно всегда будет вызывать это исключение. Следовательно, не бросайте исключение.