[英]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.