您好,登錄后才能下訂單哦!
Spring Security中怎么自定義Filter操作,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
別名 | 類名稱 | Namespace Element or Attribute |
---|---|---|
CHANNEL_FILTER | ChannelProcessingFilter | http/intercept-url@requires-channel |
SECURITY_CONTEXT_FILTER | SecurityContextPersistenceFilter | http |
CONCURRENT_SESSION_FILTER | ConcurrentSessionFilter | session-management/concurrency-control |
HEADERS_FILTER | HeaderWriterFilter | http/headers |
CSRF_FILTER | CsrfFilter | http/csrf |
LOGOUT_FILTER | LogoutFilter | http/logout |
X509_FILTER | X509AuthenticationFilter | http/x509 |
PRE_AUTH_FILTER | AbstractPreAuthenticatedProcessingFilter( Subclasses) | N/A |
CAS_FILTER | CasAuthenticationFilter | N/A |
FORM_LOGIN_FILTER | UsernamePasswordAuthenticationFilter | http/form-login |
BASIC_AUTH_FILTER | BasicAuthenticationFilter | http/http-basic |
SERVLET_API_SUPPORT_FILTER | SecurityContextHolderAwareRequestFilter | http/@servlet-api-provision |
JAAS_API_SUPPORT_FILTER | JaasApiIntegrationFilter | http/@jaas-api-provision |
REMEMBER_ME_FILTER | RememberMeAuthenticationFilter | http/remember-me |
ANONYMOUS_FILTER | AnonymousAuthenticationFilter | http/anonymous |
SESSION_MANAGEMENT_FILTER | SessionManagementFilter | session-management |
EXCEPTION_TRANSLATION_FILTER | ExceptionTranslationFilter | http |
FILTER_SECURITY_INTERCEPTOR | FilterSecurityInterceptor | http |
SWITCH_USER_FILTER | SwitchUserFilter | N/A |
過濾器順序從上到下
自定義的 Filter 建議繼承 GenericFilterBean,本文示例:
package com.example.filter; import org.springframework.web.filter.GenericFilterBean; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; /** * @author 咸魚 * @date 2019-05-26 18:02 */ public class BeforeLoginFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("在 UsernamePasswordAuthenticationFilter 前調用"); chain.doFilter(request, response); } }
配置很簡單,本文示例:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/user/**").hasAuthority("USER") .and() .formLogin().loginPage("/login").defaultSuccessUrl("/user") .and() .logout().logoutUrl("/logout").logoutSuccessUrl("/login"); // 在 UsernamePasswordAuthenticationFilter 前添加 BeforeLoginFilter http.addFilterBefore(new BeforeLoginFilter(), UsernamePasswordAuthenticationFilter.class); // 在 CsrfFilter 后添加 AfterCsrfFilter http.addFilterAfter(new AfterCsrfFilter(), CsrfFilter.class); }
說明:
HttpSecurity 有三個常用方法來配置:
addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
在 beforeFilter 之前添加 filter
addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)
在 afterFilter 之后添加 filter
addFilterAt(Filter filter, Class<? extends Filter> atFilter)
在 atFilter 相同位置添加 filter, 此 filter 不覆蓋 filter
通過在不同 Filter 的 doFilter() 方法中加斷點調試,可以判斷哪個 filter 先執行,從而判斷 filter 的執行順序 。
1、定義自己的過濾器
2、指定位置,通過HttpSecurity的方法指定
package com.qiudaozhang.springsecurity.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestHeadCheckFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { var httpRequest = (HttpServletRequest) servletRequest; var httpResponse = (HttpServletResponse) servletResponse; String requestId = httpRequest.getHeader("Request-id"); if(requestId == null || requestId.isBlank()) { httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } filterChain.doFilter(servletRequest,servletResponse); } }
package com.qiudaozhang.springsecurity.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestParamCheckFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { var httpRequest = (HttpServletRequest) servletRequest; var httpResponse = (HttpServletResponse) servletResponse; String timestamp = httpRequest.getParameter("timestamp"); if(timestamp == null || timestamp.isBlank()) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); return; } filterChain.doFilter(servletRequest,servletResponse); } }
HttpSecurity中有兩個方法,指定過濾器的位置,一個指定在誰前面,一個指定在誰后面。
public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) { this.comparator.registerAfter(filter.getClass(), afterFilter); return this.addFilter(filter); } public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) { this.comparator.registerBefore(filter.getClass(), beforeFilter); return this.addFilter(filter); }
package com.qiudaozhang.springsecurity.config; import com.qiudaozhang.springsecurity.filter.RequestHeadCheckFilter; import com.qiudaozhang.springsecurity.filter.RequestParamCheckFilter; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @Configuration public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore( new RequestHeadCheckFilter(), BasicAuthenticationFilter.class ) .addFilterAfter(new RequestParamCheckFilter(),BasicAuthenticationFilter.class) .authorizeRequests() .anyRequest() .permitAll(); } }
準備一個端點測試
package com.qiudaozhang.springsecurity.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("hello") public String hello () { return "hello"; } }
當前沒有傳遞timestamp參數,所以參照約定,過濾器直接給出403.
關于Spring Security中怎么自定義Filter操作問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。