亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是SpringSecurity過濾器

發布時間:2021-10-12 09:21:41 來源:億速云 閱讀:107 作者:iii 欄目:編程語言

這篇文章主要介紹“什么是SpringSecurity過濾器”,在日常操作中,相信很多人在什么是SpringSecurity過濾器問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是SpringSecurity過濾器”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前置知識

我們知道Spring Security是通過Filter的方式來完成它的核心流程。但是:

  1. Spring Security到底擁有哪些Filter?

  2. 這些Filter是如何注入容器?

  3. 我們如何自定義自己的Filter?

web.xml配置

前面我們已經介紹過了,最開始如果我們要配置Filter,一般是通過web.xml的方式:

<filter>  
   <filter-name>deleFilter</filter-name>  
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
   <init-param>  
      <param-name>targetBeanName</param-name>  
      <param-value>spring-bean-name</param-value>  
   </init-param>  
</filter>          
<filter-mapping>  
   <filter-name>deleFilter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>

SpringBoot中添加Filter

在SpringBoot中可以通過@WebFilter和@ServletComponentScan注解,注入自定義的Filter。

@WebFilter(filterName = "myFilter",urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    }

    @Override
    public void destroy() {
    }
}

@SpringBootApplication
@ServletComponentScan(basePackages = "vip.mycollege.filter")
public class StartApplication {

    public static void main(String[] args) {
        SpringApplication.run(StartApplication.class, args);
    }
}

也可以通過FilterRegistrationBean的方式,注入自定義的Filter。

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new MyFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }
}

也可以通過DelegatingFilterProxyRegistrationBean的方式。

@Configuration
public class FilterConfig {
    @Bean("proxyFilter")
    public Filter filter (){
        return new Filter() {
            @Override
            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
            }

            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
            }

            @Override
            public void destroy() {
            }
        
    @Bean
    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){
        DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean("proxyFilter");
        bean.addUrlPatterns("/*");
        return bean;
    }
}

DelegatingFilterProxyRegistrationBean和FilterRegistrationBean都繼承了AbstractFilterRegistrationBean,從名字上看就知道是一個RegistrationBean,也就是說會在Servlet容器啟動的時候被注入。

DelegatingFilterProxyRegistrationBean會在Servlet容器中注冊一個DelegatingFilterProxy,用來代理Spring IoC容器中某個指定名稱的Filter bean。

FilterChainProxy

SpringBoot有一個SecurityFilterAutoConfiguration的自動配置類,就會配置一個name為springSecurityFilterChain的DelegatingFilterProxyRegistrationBean,這個類的url-pattern默認為/*,也就是說會過濾所有的請求。

name是springSecurityFilterChain是一個什么鬼呢?

答案是:FilterChainProxy。

這個類是在HttpSecurityBeanDefinitionParser的registerFilterChainProxyIfNecessary方法中注冊。

HttpSecurityBeanDefinitionParser也是一個BeanDefinitionParser,因此它會通過parse方法來構建Filter類。

整個流程現在就清晰了:

  1. SpringBoot通過自動配置類搞了個DelegatingFilterProxyRegistrationBean

  2. DelegatingFilterProxyRegistrationBean會在Servlet啟動的時候注冊一個DelegatingFilterProxy

  3. DelegatingFilterProxy會默認會攔截所有的請求,然后交個一個別名為springSecurityFilterChain的FilterChainProxy

  4. FilterChainProxy在持有一個SecurityFilterChain的list

  5. SecurityFilterChain本身又持有一個Filter列表,可以通過match找出url匹配的Request交個filters處理

FilterChainProxy除了持有過濾器,默認內置了一個StrictHttpFirewall一個HTTP防火墻,它采用了嚴格模式,遇到任何可疑的請求,會通過拋出異常RequestRejectedException拒絕該請求。

現在我們知道了Spring Security如何收集利用Filter了。

但是,Spring Security到底背著我們弄了哪些Filter呢?

我只想說很多,要知道有哪些也很簡單,在FilterChainProxy打一個斷點,debug,看一下filterChains變量中的filters列表就能看到有哪些filter

默認情況下filterChains只有一個filte,就是DefaultSecurityFilterChain,看名字就知道這是一個SecurityFilterChain,他包含了一個Filter列表,默認有:

  1. WebAsyncManagerIntegrationFilter:與處理異步請求映射的 WebAsyncManager 進行集成

  2. SecurityContextPersistenceFilter: 請求前保存和請求后清除SecurityContextHolder中的安全上下文

  3. HeaderWriterFilter:將頭信息加入響應中

  4. CsrfFilter:處理跨站請求偽造

  5. LogoutFilter:處理登出

  6. UsernamePasswordAuthenticationFilter:處理基于表單的登錄

  7. DefaultLoginPageGeneratingFilter:如果沒有配置登錄頁,生成默認登錄頁

  8. DefaultLogoutPageGeneratingFilter:如果沒有登出頁,生成默認登出頁

  9. BasicAuthenticationFilter:處理HTTP BASIC認證

  10. RequestCacheAwareFilter:處理請求的緩存

  11. SecurityContextHolderAwareRequestFilter:包裝請求對象request

  12. AnonymousAuthenticationFilter:檢測SecurityContextHolder是否存在Authentication,如不存在提供一個匿名 Authentication

  13. SessionManagementFilter:管理 session 的過濾器

  14. ExceptionTranslationFilter:處理 AccessDeniedException 和 AuthenticationException 異常

  15. FilterSecurityInterceptor: 權限校驗相關

重要Filter

UsernamePasswordAuthenticationFilter

UsernamePasswordAuthenticationFilter本身沒啥好說的,它就是一個Filter,但是因為它用得多,所以說一下。

Filter肯定先看doFilter方法,UsernamePasswordAuthenticationFilter的主要認證邏輯在attemptAuthentication:

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException {
    if (this.postOnly && !request.getMethod().equals("POST")) {
        throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
    }
    String username = obtainUsername(request);
    username = (username != null) ? username : "";
    username = username.trim();
    String password = obtainPassword(request);
    password = (password != null) ? password : "";
    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
    setDetails(request, authRequest);
    return this.getAuthenticationManager().authenticate(authRequest);
}

很簡單,就是從request中獲取username和password的字段,封裝成UsernamePasswordAuthenticationToken,然后扔給AuthenticationManager去執行認證,當然,最終認證邏輯肯定是像DaoAuthenticationProvider 這樣的AuthenticationProvider執行。

FilterSecurityInterceptor

FilterSecurityInterceptor主要是用來做權限校驗的,具體的鑒權邏輯主要在AbstractSecurityInterceptor中。

FilterSecurityInterceptor也是一個Filter,所以,還是先看doFilter方法,調用了invoke:

public void invoke(FilterInvocation filterInvocation) throws IOException, ServletException {
        //一次請求中避免重復檢查
		if (isApplied(filterInvocation) && this.observeOncePerRequest) {
			filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse());
			return;
		}
		// 第一次調用,先設置標記,避免重復調用
		if (filterInvocation.getRequest() != null && this.observeOncePerRequest) {
			filterInvocation.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
		}
        // 業務邏輯調用之前,執行檢查鑒權操作主要就是在這里面完成
		InterceptorStatusToken token = super.beforeInvocation(filterInvocation);
		try {
            // 執行具體的業務邏輯
			filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse());
		}
		finally {
			super.finallyInvocation(token);
		}
        // 業務邏輯調用之后,主要是處理返回結果
		super.afterInvocation(token, null);
	}

FilterInvocation就是FilterInvocation、ServletResponse、FilterChain的簡單封裝。

我們看到整個invoke的邏輯非常清晰,很像AOP的around結構。

ExceptionTranslationFilter

ExceptionTranslationFilter的邏輯有點奇怪,它主要是為了處理 AccessDeniedException 和 AuthenticationException 異常。但是并不是處理它前面產生的異常,而是它后面的Filter產生的異常,因為它前面Filter如果異常了根本到不了它這里。

它后面,默認就只有FilterSecurityInterceptor了,主要會產生AccessDeniedException授權異常,AuthenticationException是因為有一個再認證的過程。

過濾器

  • WebAsyncManagerIntegrationFilter

  • SecurityContextPersistenceFilter

  • ChannelProcessingFilter

  • ConcurrentSessionFilter

  • HeaderWriterFilter

  • CorsFilter

  • CsrfFilter

  • LogoutFilter

  • OAuth3AuthorizationRequestRedirectFilter

  • Saml2WebSsoAuthenticationRequestFilter

  • X509AuthenticationFilter

  • AbstractPreAuthenticatedProcessingFilter

  • CasAuthenticationFilter

  • OAuth3LoginAuthenticationFilter

  • Saml2WebSsoAuthenticationFilter

  • UsernamePasswordAuthenticationFilter

  • ConcurrentSessionFilter

  • OpenIDAuthenticationFilter

  • DefaultLoginPageGeneratingFilter

  • DefaultLogoutPageGeneratingFilter

  • DigestAuthenticationFilter

  • BearerTokenAuthenticationFilter

  • BasicAuthenticationFilter

  • RequestCacheAwareFilter

  • SecurityContextHolderAwareRequestFilter

  • JaasApiIntegrationFilter

  • RememberMeAuthenticationFilter

  • AnonymousAuthenticationFilter

  • OAuth3AuthorizationCodeGrantFilter

  • SessionManagementFilter

  • ExceptionTranslationFilter

  • SwitchUserFilter

  • FilterSecurityInterceptor

到此,關于“什么是SpringSecurity過濾器”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

夏河县| 和平县| 安丘市| 休宁县| 从化市| 平和县| 吕梁市| 五峰| 神农架林区| 城固县| 来凤县| 松原市| 翁牛特旗| 海城市| 肇庆市| 扎兰屯市| 沿河| 宝清县| 沂水县| 兰西县| 武隆县| 合阳县| 佳木斯市| 达尔| 临沧市| 冷水江市| 巩义市| 绥化市| 林甸县| 河北区| 云林县| 万山特区| 绿春县| 云和县| 深泽县| 潮安县| 马鞍山市| 乌苏市| 广东省| 玛曲县| 厦门市|