繁体   English   中英

多次调用 Spring 安全自定义过滤器

[英]Spring security custom filter called multiple times

我有一个名为六次的自定义注销过滤器。 我尝试访问应用程序后两次,当我输入用户名/密码并单击“登录”时两次,然后当我单击“注销”时再次两次。

我究竟做错了什么?

配置:

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN_FUNCTIONS')" />      
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

    <form-login login-page="/login"
        authentication-success-handler-ref="customAuthenticationSuccessHandlerBean"
        authentication-failure-handler-ref="customAuthenticationFailureHandlerBean" />
    <logout invalidate-session="true" success-handler-ref="logoutHandlerBean" />
    <session-management session-fixation-protection="migrateSession">
        <concurrency-control max-sessions="1"
            expired-url="/login_sessionexpired" />
    </session-management>

    <custom-filter before="LOGOUT_FILTER" ref="customLogoutFilter" />
</http>

<beans:bean id="customLogoutFilter" class="com.hurontg.libms.security.CustomLogoutFilter" />

过滤器:

public class CustomLogoutFilter extends OncePerRequestFilter {
/**
 * 
 */
private XLogger logger = XLoggerFactory
        .getXLogger(CustomLogoutFilter.class.getName());

@Override
protected void doFilterInternal(HttpServletRequest req,
        HttpServletResponse res, FilterChain chain)
        throws ServletException, IOException {

    logger.error("========================================================================================");
    logger.error("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Custom Logout Filter $$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
    logger.error("========================================================================================");

    chain.doFilter(req, res);
}

}

Spring 版本:4.1.1 Spring 安全性:3.2.5

如果您在使用Spring启动,任何GenericFilterBean (OncePerRequestFilter就是其中之一)的背景下,将被自动添加到过滤器链。 这意味着您上面的配置将包含两次相同的过滤器。

最简单的解决方法是在上下文中定义一个FilterRegistrationBean并禁用它:

<beans:bean id="customLogoutFilterRegistration" class="org.springframework.boot.context.embedded.FilterRegistrationBean">
    <beans:property name="filter" ref="customLogoutFilter"/>
    <beans:property name="enabled" value="false"/>
</beans:bean>

编辑(11/3/2020):

对于在 SpringBoot 中工作并希望使用注释注册 bean 的任何人。 在 Spring Boot 应用程序初始值设定项文件(带有 @SpringBootApplication 注释的一个)中添加以下代码:

@Bean
public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new YourCustomFilterClassName());
    registrationBean.setEnabled(false);
    return registrationBean;
}

它可能会被请求的其他 URL 调用。 例如,如果您有任何 css、javascript、图像加载到页面上,它将为每个图像调用。 尝试添加一个显示当前请求信息的日志语句,以确定是否是这种情况。 例如,

logger.error("URL = " + req.getRequestURL());

只是分享我的案例:(

我没有在 AuthenticationProvider 中设置authentication.setAuthenticated(true)

因此, AbstractPreAuthenticatedProcessingFilter调用了一次authenticate ,然后AbstractSecurityInterceptor也调用了authenticateIfNeeded

Spring security 有大约 12 个过滤器,其中一些会尝试检查用户是否通过身份验证。 例如,有一个名为 AnonymousAuthenticationFilter 的过滤器。

如果您提供身份验证提供程序并且已对请求进行一次身份验证,则应在安全上下文中设置身份验证对象。

SecurityContextHolder.getContext().setAuthentication(authentication)

在示例中, AnonymousAuthenticationFilter 尝试从安全上下文中获取身份验证。 如果没有找到,它会再次拨打电话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM