Chuỗi bộ lọc bảo mật Spring hoạt động như thế nào


135

Tôi nhận thấy rằng bảo mật Spring xây dựng trên chuỗi các bộ lọc, sẽ chặn yêu cầu, phát hiện (không có) xác thực, chuyển hướng đến điểm nhập xác thực hoặc chuyển yêu cầu đến dịch vụ ủy quyền và cuối cùng để yêu cầu chạm vào servlet hoặc ném ngoại lệ bảo mật (không được xác thực hoặc trái phép). DelegatingFitlerProxy dán các bộ lọc này lại với nhau. Để thực hiện các tác vụ của mình, các bộ lọc này truy cập các dịch vụ như UserDetailsServicexác thực .

Các bộ lọc chính trong chuỗi là (theo thứ tự)

  • SecurityContextPersistenceFilter (khôi phục Xác thực từ JSESSIONID)
  • UsernamePasswordAuthenticationFilter (thực hiện xác thực)
  • ExceptionTranslationFilter (bắt ngoại lệ bảo mật từ FilterSecurityInterceptor)
  • FilterSecurityInterceptor (có thể ném ngoại lệ xác thực và ủy quyền)

Tôi bối rối không biết các bộ lọc này được sử dụng như thế nào. Có phải là cho mùa xuân cung cấp mẫu đăng nhập, UsernamePasswordAuthenticationFilter chỉ được sử dụng cho / đăng nhập , còn các bộ lọc sau thì không? Liệu hình thức đăng nhập yếu tố không gian tên tự động cấu hình các bộ lọc này? Có phải mọi yêu cầu (được xác thực hay không) đều đạt đến FilterSecurityInterceptor cho url không đăng nhập?

Điều gì xảy ra nếu tôi muốn bảo mật API REST của mình bằng mã thông báo JWT , được lấy từ đăng nhập? Tôi phải cấu hình hai httpthẻ cấu hình không gian tên , quyền? Một cho / login với UsernamePasswordAuthenticationFilter, và một số khác cho url của REST, với tùy chỉnh JwtAuthenticationFilter.

Liệu cấu hình hai httpyếu tố tạo ra hai springSecurityFitlerChains? Được UsernamePasswordAuthenticationFiltertắt theo mặc định, cho đến khi tôi tuyên bố form-login? Làm cách nào để thay thế SecurityContextPersistenceFilterbằng bộ lọc sẽ thu được Authenticationtừ hiện tại JWT-tokenthay vì JSESSIONID?


Thứ tự mặc định của các bộ lọc được xác định trong org.springframework.security.config.annotation.web.builders.FilterComparator
blacelle

Câu trả lời:


210

Chuỗi bộ lọc bảo mật Spring là một công cụ rất phức tạp và linh hoạt.

Các bộ lọc chính trong chuỗi là (theo thứ tự)

  • SecurityContextPersistenceFilter (khôi phục Xác thực từ JSESSIONID)
  • UsernamePasswordAuthenticationFilter (thực hiện xác thực)
  • ExceptionTranslationFilter (bắt ngoại lệ bảo mật từ FilterSecurityInterceptor)
  • FilterSecurityInterceptor (có thể ném ngoại lệ xác thực và ủy quyền)

Nhìn vào tài liệu phát hành ổn định 4.2.1 hiện tại , phần 13.3 Đặt hàng bộ lọc, bạn có thể thấy toàn bộ tổ chức bộ lọc của chuỗi bộ lọc:

13.3 Đặt hàng bộ lọc

Thứ tự mà các bộ lọc được xác định trong chuỗi là rất quan trọng. Bất kể bạn đang sử dụng bộ lọc nào, thứ tự sẽ như sau:

  1. ChannelProcessingFilter , vì có thể cần phải chuyển hướng đến một giao thức khác

  2. SecurityContextPersistenceFilter , do đó SecurityContext có thể được thiết lập trong SecurityContextHolder khi bắt đầu yêu cầu web và mọi thay đổi đối với SecurityContext có thể được sao chép sang httpSession khi yêu cầu web kết thúc (sẵn sàng để sử dụng với yêu cầu web tiếp theo)

  3. Đồng thờiSessionFilter , vì nó sử dụng chức năng SecurityContextHolder và cần cập nhật SessionRegistry để phản ánh các yêu cầu đang diễn ra từ hiệu trưởng

  4. Các cơ chế xử lý xác thực - UsernamePasswordAuthenticationFilter , CasAuthenticationFilter , BasicAuthenticationFilter , v.v. - để SecurityContextHolder có thể được sửa đổi để chứa mã thông báo yêu cầu xác thực hợp lệ

  5. Các SecurityContextHolderAwareRequestFilter , nếu bạn đang sử dụng nó để cài đặt một mùa xuân an ninh biết HttpServletRequestWrapper vào container servlet của bạn

  6. Các JaasApiIntegrationFilter , nếu một JaasAuthenticationToken là trong SecurityContextHolder này sẽ xử lý FilterChain như Chủ đề trong JaasAuthenticationToken

  7. Ghi nhớ MeAuthenticationFilter , để nếu không có cơ chế xử lý xác thực trước đó cập nhật SecurityContextHolder và yêu cầu xuất hiện một cookie cho phép các dịch vụ ghi nhớ diễn ra, một đối tượng Xác thực được ghi nhớ phù hợp sẽ được đặt ở đó

  8. AnonymousAuthenticationFilter , để nếu không có cơ chế xử lý xác thực trước đó cập nhật SecurityContextHolder, một đối tượng Xác thực ẩn danh sẽ được đặt ở đó

  9. ExceptionTranslationFilter , để bắt bất kỳ trường hợp ngoại lệ nào của Spring Security để có thể trả về phản hồi lỗi HTTP hoặc xác thực phù hợpEntryPoint có thể được khởi chạy

  10. FilterSecurityInterceptor , để bảo vệ các URI web và nâng cao ngoại lệ khi quyền truy cập bị từ chối

Bây giờ, tôi sẽ cố gắng tiếp tục từng câu hỏi của bạn:

Tôi bối rối không biết các bộ lọc này được sử dụng như thế nào. Có phải là cho mùa xuân cung cấp mẫu đăng nhập, UsernamePasswordAuthenticationFilter chỉ được sử dụng cho / đăng nhập, còn các bộ lọc sau thì không? Phần tử không gian tên đăng nhập biểu mẫu có tự động cấu hình các bộ lọc này không? Có phải mọi yêu cầu (được xác thực hay không) đều đạt đến FilterSecurityInterceptor cho url không đăng nhập?

Khi bạn đang định cấu hình một <security-http>phần, đối với mỗi phần, bạn ít nhất phải cung cấp một cơ chế xác thực. Đây phải là một trong những bộ lọc khớp với nhóm 4 trong phần Đặt hàng bộ lọc 13.3 từ tài liệu Bảo mật mùa xuân mà tôi vừa tham khảo.

Đây là bảo mật hợp lệ tối thiểu: phần tử http có thể được cấu hình:

<security:http authentication-manager-ref="mainAuthenticationManager" 
               entry-point-ref="serviceAccessDeniedHandler">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
</security:http>

Chỉ cần làm điều đó, các bộ lọc này được cấu hình trong proxy chuỗi bộ lọc:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "6": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "7": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "8": "org.springframework.security.web.session.SessionManagementFilter",
        "9": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "10": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Lưu ý: Tôi nhận được chúng bằng cách tạo một RestContoder đơn giản mà @Autowires FilterChainProxy và trả về nội dung của nó:

    @Autowired
    private FilterChainProxy filterChainProxy;

    @Override
    @RequestMapping("/filterChain")
    public @ResponseBody Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        return this.getSecurityFilterChainProxy();
    }

    public Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        Map<Integer, Map<Integer, String>> filterChains= new HashMap<Integer, Map<Integer, String>>();
        int i = 1;
        for(SecurityFilterChain secfc :  this.filterChainProxy.getFilterChains()){
            //filters.put(i++, secfc.getClass().getName());
            Map<Integer, String> filters = new HashMap<Integer, String>();
            int j = 1;
            for(Filter filter : secfc.getFilters()){
                filters.put(j++, filter.getClass().getName());
            }
            filterChains.put(i++, filters);
        }
        return filterChains;
    }

Ở đây chúng ta có thể thấy rằng chỉ bằng cách khai báo <security:http>phần tử với một cấu hình tối thiểu, tất cả các bộ lọc mặc định đều được bao gồm, nhưng không có bộ lọc nào thuộc loại Xác thực (nhóm thứ 4 trong phần Đặt hàng Bộ lọc 13.3). Vì vậy, nó thực sự có nghĩa là chỉ bằng cách khai báo security:httpphần tử, SecurityContextPersistenceFilter, ExceptionTranslationFilter và FilterSecurityInterceptor được cấu hình tự động.

Trong thực tế, một cơ chế xử lý xác thực nên được cấu hình và thậm chí các yêu cầu xử lý không gian tên bảo mật cho điều đó, gây ra lỗi trong khi khởi động, nhưng có thể bỏ qua việc thêm thuộc tính ref-point-ref <http:security>

Nếu tôi thêm một cơ bản <form-login>vào cấu hình, theo cách này:

<security:http authentication-manager-ref="mainAuthenticationManager">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
    <security:form-login />
</security:http>

Bây giờ, bộ lọcChain sẽ như thế này:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter",
        "6": "org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter",
        "7": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "8": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "9": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "10": "org.springframework.security.web.session.SessionManagementFilter",
        "11": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "12": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Bây giờ, điều này hai bộ lọc org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter và org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter được tạo ra và cấu hình trong FilterChainProxy.

Vì vậy, bây giờ, các câu hỏi:

Có phải là cho mùa xuân cung cấp mẫu đăng nhập, UsernamePasswordAuthenticationFilter chỉ được sử dụng cho / đăng nhập, còn các bộ lọc sau thì không?

Có, nó được sử dụng để cố gắng hoàn thành cơ chế xử lý đăng nhập trong trường hợp yêu cầu khớp với url UsernamePasswordAuthenticationFilter. Url này có thể được cấu hình hoặc thậm chí thay đổi hành vi của nó để phù hợp với mọi yêu cầu.

Bạn cũng có thể có nhiều hơn một cơ chế xử lý Xác thực được định cấu hình trong cùng một FilterchainProxy (chẳng hạn như HttpBasic, CAS, v.v.).

Phần tử không gian tên đăng nhập biểu mẫu có tự động cấu hình các bộ lọc này không?

Không, phần tử đăng nhập biểu mẫu định cấu hình UsernamePasswordAUthenticationFilter và trong trường hợp bạn không cung cấp url trang đăng nhập, nó cũng cấu hình org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter trang.

Các bộ lọc khác được cấu hình tự động theo mặc định chỉ bằng cách tạo một <security:http>phần tử không có security:"none"thuộc tính.

Có phải mọi yêu cầu (được xác thực hay không) đều đạt đến FilterSecurityInterceptor cho url không đăng nhập?

Mọi yêu cầu phải đạt được nó, vì đó là yếu tố quan tâm đến việc yêu cầu đó có quyền truy cập url được yêu cầu hay không. Nhưng một số bộ lọc được xử lý trước đó có thể dừng xử lý chuỗi bộ lọc mà không gọi FilterChain.doFilter(request, response);. Ví dụ: bộ lọc CSRF có thể dừng xử lý chuỗi bộ lọc nếu yêu cầu không có tham số csrf.

Điều gì xảy ra nếu tôi muốn bảo mật API REST của mình bằng mã thông báo JWT, được lấy từ đăng nhập? Tôi phải cấu hình hai thẻ http cấu hình không gian tên, quyền? Một cái khác cho / đăng nhập với UsernamePasswordAuthenticationFilter, và một cái khác cho url của REST, với tùy chỉnh JwtAuthenticationFilter.

Không, bạn không bị buộc phải làm theo cách này. Bạn có thể khai báo cả hai UsernamePasswordAuthenticationFilterJwtAuthenticationFiltertrong cùng một phần tử http, nhưng nó phụ thuộc vào hành vi cụ thể của từng bộ lọc này. Cả hai cách tiếp cận đều có thể, và lựa chọn nào để lựa chọn tài chính tùy thuộc vào sở thích riêng.

Việc cấu hình hai phần tử http có tạo ra hai springSecurityFitlerChains không?

Vâng đó là sự thật

UsernamePasswordAuthenticationFilter bị tắt theo mặc định, cho đến khi tôi khai báo mẫu đăng nhập?

Có, bạn có thể thấy nó trong các bộ lọc được nâng lên trong mỗi cấu hình tôi đã đăng

Làm cách nào để thay thế SecurityContextPersistenceFilter bằng một cái, cái này sẽ có được Xác thực từ mã thông báo JWT hiện tại thay vì JSESSIONID?

Bạn có thể tránh SecurityContextPersistenceFilter, chỉ cần cấu hình chiến lược phiên trong <http:element>. Chỉ cần cấu hình như thế này:

<security:http create-session="stateless" >

Hoặc, trong trường hợp này, bạn có thể ghi đè lên nó bằng một bộ lọc khác, theo cách này bên trong <security:http>phần tử:

<security:http ...>  
   <security:custom-filter ref="myCustomFilter" position="SECURITY_CONTEXT_FILTER"/>    
</security:http>
<beans:bean id="myCustomFilter" class="com.xyz.myFilter" />

BIÊN TẬP:

Một câu hỏi về "Bạn cũng có thể có nhiều hơn một cơ chế xử lý Xác thực được định cấu hình trong cùng một FilterchainProxy". Cái sau sẽ ghi đè xác thực được thực hiện bởi cái đầu tiên, nếu khai báo nhiều bộ lọc xác thực (thực hiện Spring)? Làm thế nào điều này liên quan đến việc có nhiều nhà cung cấp xác thực?

Điều này cuối cùng phụ thuộc vào việc thực hiện từng bộ lọc, nhưng thực tế là các bộ lọc xác thực sau ít nhất có thể ghi đè lên bất kỳ xác thực trước đó cuối cùng được thực hiện bởi các bộ lọc trước đó.

Nhưng điều này sẽ không xảy ra. Tôi có một số trường hợp sản xuất trong các dịch vụ REST được bảo mật trong đó tôi sử dụng một loại mã thông báo ủy quyền có thể được cung cấp cả dưới dạng tiêu đề http hoặc bên trong thân yêu cầu. Vì vậy, tôi định cấu hình hai bộ lọc phục hồi mã thông báo đó, trong một trường hợp từ Tiêu đề http và bộ lọc khác từ thân yêu cầu của yêu cầu nghỉ ngơi riêng. Đúng là nếu một yêu cầu http cung cấp mã thông báo xác thực đó dưới dạng tiêu đề http và bên trong thân yêu cầu, cả hai bộ lọc sẽ cố gắng thực thi cơ chế xác thực ủy quyền cho người quản lý, nhưng có thể dễ dàng tránh được việc kiểm tra xem yêu cầu có phải là dễ dàng không đã được xác thực ngay khi bắt đầu doFilter()phương thức của từng bộ lọc.

Có nhiều bộ lọc xác thực có liên quan đến việc có nhiều hơn một nhà cung cấp xác thực, nhưng đừng ép buộc. Trong trường hợp tôi tiếp xúc trước đây, tôi có hai bộ lọc xác thực nhưng tôi chỉ có một nhà cung cấp xác thực, vì cả hai bộ lọc đều tạo cùng một loại đối tượng Xác thực nên trong cả hai trường hợp, trình quản lý xác thực ủy quyền cho cùng một nhà cung cấp.

Và ngược lại với điều này, tôi cũng có một kịch bản khi tôi chỉ xuất bản một UsernamePasswordAuthenticationFilter nhưng cả hai thông tin người dùng đều có thể được chứa trong DB hoặc LDAP, vì vậy tôi có hai nhà cung cấp hỗ trợ UsernamePasswordAuthenticationToken và ủy quyền cho nhà cung cấp xác thực bảo mật để xác thực các thông tin.

Vì vậy, tôi nghĩ rõ ràng rằng cả số lượng bộ lọc xác thực không xác định số lượng nhà cung cấp xác thực cũng như số lượng nhà cung cấp xác định số lượng bộ lọc.

Ngoài ra, tài liệu nêu rõ SecurityContextPersistenceFilter chịu trách nhiệm làm sạch SecurityContext, đây là nhóm chủ đề quan trọng. Nếu tôi bỏ qua nó hoặc cung cấp thực hiện tùy chỉnh, tôi phải thực hiện việc làm sạch bằng tay, phải không? Có nhiều gotcha tương tự khi tùy chỉnh chuỗi không?

Tôi đã không xem xét kỹ bộ lọc này trước đây, nhưng sau câu hỏi cuối cùng của bạn, tôi đã kiểm tra việc triển khai và như thường lệ trong Spring, gần như mọi thứ đều có thể được định cấu hình, mở rộng hoặc ghi đè.

Các đại biểu SecurityContextPersistenceFilter trong triển khai SecurityContextRep repository tìm kiếm SecurityContext. Theo mặc định, một httpSessionSecurityContextRep repository được sử dụng, nhưng điều này có thể được thay đổi bằng cách sử dụng một trong các hàm tạo của bộ lọc. Vì vậy, tốt hơn là bạn nên viết SecurityContextRep repository phù hợp với nhu cầu của bạn và chỉ cần cấu hình nó trong SecurityContextPersistenceFilter, tin tưởng vào hành vi đã được chứng minh của nó thay vì bắt đầu thực hiện từ đầu.


3
Đây là lời giải thích khai sáng. Một câu hỏi về "Bạn cũng có thể có nhiều hơn một cơ chế xử lý Xác thực được định cấu hình trong cùng một FilterchainProxy". Cái sau sẽ ghi đè xác thực được thực hiện bởi cái đầu tiên, nếu khai báo nhiều bộ lọc xác thực (thực hiện Spring)? Làm thế nào điều này liên quan đến việc có nhiều nhà cung cấp xác thực?
Tuomas Toivonen

Ngoài ra, tài liệu nêu rõ SecurityContextPersistenceFilter chịu trách nhiệm làm sạch SecurityContext, đây là nhóm chủ đề quan trọng. Nếu tôi bỏ qua nó hoặc cung cấp thực hiện tùy chỉnh, tôi phải thực hiện việc làm sạch bằng tay, phải không? Có nhiều gotcha tương tự khi tùy chỉnh chuỗi không?
Tuomas Toivonen

1
@TuomasToivonen Tôi đã chỉnh sửa câu trả lời của mình sau những câu hỏi trong bình luận cuối cùng của bạn
jlumietu

1
@jlumietu Có một trích dẫn bị thiếu trong chú thích java bên cạnh ("/ filterChain) . Ngoài ra, bạn đặt phương thức này ở đâu? Tôi đã thử thêm nó vào một bộ điều khiển và tôi có:No qualifying bean of type 'org.springframework.security.web.FilterChainProxy' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Dimitri Kopriwa 18/03/17

@BigDong đảm bảo rằng bạn đã khai báo SpringSecurityFilterChain trong cả cấu hình webDB hoặc java webapp và trong cấu hình mùa xuân của bạn. Đoạn mã này phải được đưa vào Bộ điều khiển, giống như bạn đã làm. Và vâng, bạn nói đúng về câu trích dẫn còn thiếu
jlumietu 18/03/17

4

UsernamePasswordAuthenticationFilterchỉ được sử dụng cho /login, và các bộ lọc sau không?

Không, UsernamePasswordAuthenticationFiltermở rộng AbstractAuthenticationProcessingFiltervà điều này có chứa RequestMatcher, điều đó có nghĩa là bạn có thể xác định url xử lý của riêng mình, bộ lọc này chỉ xử lý các RequestMatcherurl yêu cầu, url xử lý mặc định là /login.

Các bộ lọc sau này vẫn có thể xử lý yêu cầu, nếu UsernamePasswordAuthenticationFilterthực thi chain.doFilter(request, response);.

Thêm thông tin chi tiết về đồ đạc cốt lõi

Phần tử không gian tên đăng nhập biểu mẫu có tự động cấu hình các bộ lọc này không?

UsernamePasswordAuthenticationFilterđược tạo bởi <form-login>, đây là các Bí danh và Đặt hàng Bộ lọc Chuẩn

Có phải mọi yêu cầu (được xác thực hay không) đều đạt đến FilterSecurityInterceptor cho url không đăng nhập?

Nó phụ thuộc vào việc những người điều chỉnh trước có thành công hay không, nhưng FilterSecurityInterceptorlà người điều chỉnh cuối cùng bình thường.

Việc cấu hình hai phần tử http có tạo ra hai springSecurityFitlerChains không?

Có, mỗi fitlerChain đều có RequestMatcher, nếu RequestMatcherphù hợp với yêu cầu, yêu cầu sẽ được xử lý bởi những người điều chỉnh trong chuỗi fitler.

Mặc định RequestMatcherphù hợp với tất cả các yêu cầu nếu bạn không định cấu hình mẫu hoặc bạn có thể định cấu hình url cụ thể ( <http pattern="/rest/**").

Nếu bạn muốn biết thêm về các bộ điều chỉnh, tôi nghĩ bạn có thể kiểm tra mã nguồn trong bảo mật mùa xuân. doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)


4

Bảo mật mùa xuân là một khung dựa trên bộ lọc, nó tạo ra một TƯỜNG (httpFireWall) trước ứng dụng của bạn về các bộ lọc proxy hoặc các bean được quản lý mùa xuân. Yêu cầu của bạn phải thông qua nhiều bộ lọc để tiếp cận API của bạn.

Trình tự thực hiện trong Bảo mật mùa xuân

  1. WebAsyncManagerIntegrationFilter Cung cấp tích hợp giữa SecurityContext và WebAsyncManager của Spring Web.

  2. SecurityContextPersistenceFilterBộ lọc này sẽ chỉ thực hiện một lần cho mỗi yêu cầu, Điền vào SecurityContextHolder với thông tin thu được từ SecurityContextRep repository được cấu hình trước yêu cầu và lưu lại vào kho lưu trữ sau khi yêu cầu đã hoàn thành và xóa bộ giữ ngữ cảnh.
    Yêu cầu được kiểm tra cho phiên hiện có. Nếu yêu cầu mới, SecurityContext sẽ được tạo khác nếu yêu cầu có phiên thì bối cảnh bảo mật hiện tại sẽ được lấy từ kho lưu trữ .

  3. HeaderWriterFilter Lọc thực hiện để thêm các tiêu đề cho phản ứng hiện tại.

  4. LogoutFilterNếu url yêu cầu là /logout(đối với cấu hình mặc định) hoặc nếu toán học url yêu cầu được RequestMatchercấu hình trong LogoutConfigurerthì

    • xóa bối cảnh an ninh.
    • làm mất hiệu lực phiên
    • xóa tất cả các cookie có tên cookie được cấu hình trong LogoutConfigurer
    • Chuyển hướng đến url đăng xuất mặc định /hoặc url đăng xuất thành công được cấu hình hoặc gọi logoutSuccessHandler được định cấu hình.
  5. UsernamePasswordAuthenticationFilter

    • Đối với bất kỳ url yêu cầu nào khác ngoài loginProcessingUrl, bộ lọc này sẽ không xử lý thêm nhưng chuỗi bộ lọc chỉ tiếp tục.
    • Nếu URL được yêu cầu khớp (phải HTTP POST) mặc định /loginhoặc khớp được .loginProcessingUrl()định cấu hình FormLoginConfigurersau đó UsernamePasswordAuthenticationFilterthử xác thực.
    • tham số biểu mẫu đăng nhập mặc định là tên người dùng và mật khẩu, có thể được ghi đè bằng usernameParameter(String), passwordParameter(String).
    • thiết lập .loginPage() ghi đè mặc định
    • Trong khi thử xác thực
      • một Authenticationđối tượng ( UsernamePasswordAuthenticationTokenhoặc bất kỳ triển khai nào Authenticationtrong trường hợp bộ lọc xác thực tùy chỉnh của bạn) được tạo.
      • authenticationManager.authenticate(authToken)sẽ được viện dẫn
      • Lưu ý rằng chúng tôi có thể định cấu hình bất kỳ số AuthenticationProviderphương thức xác thực nào thử tất cả các nhà cung cấp auth và kiểm tra bất kỳ supportsđối tượng authToken / xác thực nhà cung cấp xác thực nào, nhà cung cấp xác thực hỗ trợ sẽ được sử dụng để xác thực. và trả về đối tượng Xác thực trong trường hợp xác thực thành công khác ném AuthenticationException.
    • Nếu phiên xác thực thành công sẽ được tạo và authenticationSuccessHandlersẽ được gọi để chuyển hướng đến url đích được định cấu hình (mặc định là /)
    • Nếu xác thực người dùng thất bại trở thành người dùng không xác thực và chuỗi tiếp tục.
  6. SecurityContextHolderAwareRequestFilter, nếu bạn đang sử dụng nó để cài đặt một HTTPServletRequestWrapper nhận biết bảo mật Spring vào thùng chứa servlet của bạn

  7. AnonymousAuthenticationFilterPhát hiện nếu không có đối tượng Xác thực trong SecurityContextHolder, nếu không tìm thấy đối tượng xác thực, sẽ tạo Authenticationđối tượng ( AnonymousAuthenticationToken) với quyền được cấp ROLE_ANONYMOUS. Ở đây AnonymousAuthenticationTokentạo điều kiện xác định người dùng không xác thực yêu cầu tiếp theo.

Nhật ký gỡ lỗi
DEBUG - /app/admin/app-config at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@aeef7b36: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 
  1. ExceptionTranslationFilter, để bắt bất kỳ trường hợp ngoại lệ nào của Spring Security để có thể trả về phản hồi lỗi HTTP hoặc có thể khởi chạy một Xác thực phù hợpEntryPoint

  2. FilterSecurityInterceptor
    Sẽ có FilterSecurityInterceptorcái gần như cuối cùng trong chuỗi bộ lọc lấy đối tượng Xác thực từ SecurityContextvà được cấp danh sách chính quyền (vai trò được cấp) và sẽ đưa ra quyết định có cho phép yêu cầu này tiếp cận tài nguyên được yêu cầu hay không, quyết định được đưa ra bằng cách khớp với AntMatcherscấu hình được phép trong HttpSecurityConfiguration.

Hãy xem xét các trường hợp ngoại lệ 401-UnAuthorized và 403-Forbidden. Những quyết định này sẽ được thực hiện cuối cùng trong chuỗi bộ lọc

  • Người dùng chưa được xác thực đang cố truy cập tài nguyên công cộng - Được phép
  • Người dùng chưa được xác thực đang cố truy cập tài nguyên được bảo mật - 401-UnAuthorized
  • Người dùng được xác thực đang cố truy cập tài nguyên bị hạn chế (bị hạn chế cho vai trò của mình) - 403-Cấm

Lưu ý: Người dùng yêu cầu chảy không chỉ ở trên bộ lọc được đề cập, nhưng có các bộ lọc khác quá không được hiển thị ở đây (. ConcurrentSessionFilter, RequestCacheAwareFilter, SessionManagementFilter...)
Nó sẽ khác nhau khi bạn sử dụng bộ lọc tùy chỉnh auth của bạn thay vì UsernamePasswordAuthenticationFilter.
Sẽ khác nếu bạn định cấu hình bộ lọc xác thực JWT và bỏ qua .formLogin() i.e, UsernamePasswordAuthenticationFilternó sẽ trở thành trường hợp hoàn toàn khác.


Chỉ để tham khảo. Các bộ lọc trong spring-web và spring-security
Lưu ý: tham khảo tên gói trong pic , vì có một số bộ lọc khác từ orm và bộ lọc được triển khai tùy chỉnh của tôi.

nhập mô tả hình ảnh ở đây

Từ Tài liệu sắp xếp thứ tự các bộ lọc được đưa ra là

  • Bộ lọc kênh
  • Đồng thờiSessionFilter
  • SecurityContextPersistenceFilter
  • Đăng xuất bộ lọc
  • Bộ lọc X509Authentication
  • Tóm tắtPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • Tên người dùngPasswordAuthenticationFilter
  • Đồng thờiSessionFilter
  • OpenIDAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • Đồng thờiSessionFilter
  • DigestAuthenticationFilter
  • BearerTokenAuthenticationFilter
  • Bộ lọc cơ bản
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApiIntegrationFilter
  • Ghi nhớAilenticationFilter
  • AnonymousAuthenticationFilter
  • Trình quản lý phiên
  • ExceptionTranslationFilter
  • FilterSecurityInterceptor
  • SwitchUserFilter

Bạn cũng có thể tham khảo
cách phổ biến nhất để xác thực một ứng dụng web hiện đại?
sự khác biệt giữa xác thực và ủy quyền trong bối cảnh của Spring Security?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.