我想用验证码来保护我的登录,因此我为身份验证过程配置了一个过滤器。验证码验证和身份验证仍然有效,就像我从日志中看到的那样,但在身份验证之后,我不会重定向回客户端。下面是我的配置:
@Bean
@Order(2)
fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
val authFilter = authenticationFilter()
if (captchaEnabled) {
http.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter::class.java)
}
val filterChain =
http.authorizeHttpRequests { authorize ->
authorize
.requestMatchers(
"/api/v1/auth-service/.well-known/jwks.json",
"/error",
"/login",
"/images/**",
"/css/**",
"/js/**",
"/templates/**",
"favicon.ico",
).permitAll()
.anyRequest().authenticated()
}
.formLogin { it.loginPage("/login").permitAll() }
.cors { it.configurationSource(corsConfigurationSource()) }.build()
if (captchaEnabled) {
val authManager = http.getSharedObject(AuthenticationManager::class.java)
authFilter.setAuthenticationManager(authManager)
}
return filterChain
}
fun authenticationFilter() =
CaptchaLoginFilter(captchaService).apply {
setAuthenticationFailureHandler(SimpleUrlAuthenticationFailureHandler("/login?error=true"))
}
字符串
如果我禁用特性标志captchaEnabled
或者只是注解掉以http.addFilterBefore
开头的行,它就能像预期的那样工作。
我的过滤器代码:
class CaptchaLoginFilter(
private val captchaService: CaptchaService?,
) : UsernamePasswordAuthenticationFilter() {
override fun attemptAuthentication(
request: HttpServletRequest,
response: HttpServletResponse,
): Authentication? {
if (!request.method.equals("POST")) {
throw AuthenticationServiceException("Authentication method not supported: " + request.method)
}
val recaptchaFormResponse = request.getParameter("g-recaptcha-response")
try {
captchaService?.processResponse(
recaptchaFormResponse,
request.remoteAddr,
null,
request.getHeader("User-Agent"),
)
} catch (e: Exception) {
when (e) {
is RecaptchaException -> {
// TODO
// request.getRequestDispatcher("otp_login").forward(request, response)
}
else ->
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.message)
} catch (ioException: IOException) {
ioException.printStackTrace()
}
}
return null
}
try {
return super.attemptAuthentication(request, response)
} catch (e: Exception) {
when (e) {
is AuthenticationException -> {
throw e
}
else -> {
logger.warn("Unexpected exception during authentication", e)
response.sendRedirect("/login?error")
return null
}
}
}
}
}
型
我可以从日志中看到,身份验证成功,就像这个过滤器被禁用一样,所以这意味着super. authorization(request,response)在最后被正确调用。在这个场景中,我没有接触请求和响应对象,所以我不知道是什么改变了行为。有什么想法吗?提前感谢。
1条答案
按热度按时间jk9hmnmh1#
您替换了整个
usernamepasswordfilter
。这导致无法加载某些默认配置。您可以参考FormLoginConfigurer
和AbstractAuthenticationFilterConfigurer
进行配置。这里,您没有有效的successHandler
。