簡體   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