这是我的代码
package com.fnot.backend.config.spring.security
import com.fnot.backend.config.external.telegram.TelegramConfig
import com.fnot.backend.domain.external.telegram.bot.service.TelegramBotService
import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.web.filter.OncePerRequestFilter
@Component
class TelegramAuthenticationFilter(
telegramConfig: TelegramConfig,
private val telegramBotService: TelegramBotService
): OncePerRequestFilter() {
private val botToken = telegramConfig.botToken
override fun doFilterInternal(
request: HttpServletRequest,
response: HttpServletResponse,
filterChain: FilterChain
) {
val authHeader = request.getHeader("TG-Authorization")
if(authHeader == null) {
filterChain.doFilter(request, response)
return
}
val tmaAuthData = TmaAuthData(authHeader, botToken)
if (tmaAuthData.isValid()) {
val telegramUserData = tmaAuthData.getTelegramUserData()
val user = telegramBotService.registerOrUpdateUserTma(telegramUserData)
val authToken = TelegramAuthenticationToken(user.id!!)
SecurityContextHolder.getContext().authentication = authToken
}
filterChain.doFilter(request, response)
}
}
它的作用:
问题是什么: 我注意到,如果 spring 抛出异常(例如在数据库中找不到行),那么它不会像通常那样映射到
500
响应代码,而是映射到 403
问题: 如何更改过滤器,以便 Spring 不会将任意未处理的异常映射到
403
,而是将它们映射到 500
这是我的
SecurityConfig
package com.fnot.backend.config.spring.security
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import org.springframework.web.filter.CorsFilter
@Configuration
@EnableWebSecurity
class SecurityConfig(
private val telegramAuthenticationFilter: TelegramAuthenticationFilter
) {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http
.csrf { it.disable() }
.cors { } // Enable CORS
.authorizeHttpRequests { auth ->
auth.requestMatchers("/").permitAll()
.anyRequest().authenticated()
}
.addFilterBefore(telegramAuthenticationFilter, UsernamePasswordAuthenticationFilter::class.java)
return http.build()
}
@Bean
fun corsFilter(): CorsFilter {
val source = UrlBasedCorsConfigurationSource()
val config = CorsConfiguration()
config.allowCredentials = true
config.addAllowedOriginPattern("*") // Allow all origins
config.addAllowedHeader("*") // Allow all headers
config.addAllowedMethod("*") // Allow all methods
source.registerCorsConfiguration("/**", config)
return CorsFilter(source)
}
}
我尝试调试
ExceptionTranslationFilter
,它首先将异常捕获为ServletException
,并以底层业务逻辑异常为原因(例如未找到数据库中的行),但随后当它进一步处理时,它会得到一个AccessDeniedExceptionThrown
来自 AuthorizationFilter
doFilterMethod()
解决方案如下。这就像 Spring Security 6 的一个非常意想不到的新功能什么的。我自己很难弄清楚。