SpringSecurity中文文檔(Servlet Session Management)

Authentication Persistence and Session Management

一旦您擁有了正在對請求進行身份驗證的應用程序,就必須考慮如何在將來的請求中持久化和恢復結果身份驗證。

默認情況下,這是自動完成的,因此不需要額外的代碼,盡管了解 requireExplicitSave在 HttpSecurity 中的含義非常重要。

如果您愿意,您可以關于 RequureExplicSave 正在做什么 requireExplicitSave is doing 或者為什么它很重要why it’s important的內容。否則,在大多數情況下您將完成本節。

但是在離開之前,考慮一下這些用例是否適合您的應用程序:

  • 我想了解會話管理的組成部分(I want to Understand Session Management’s components)
  • 我想限制用戶可以同時登錄的次數(I want to restrict the number of times a user can be logged in concurrently)
  • 我想自己直接存儲身份驗證,而不是由 Spring Security 代勞(I want to store the authentication directly myself instead of Spring Security doing it for me)
  • 我正在手動存儲身份驗證,我想刪除它(I am storing the authentication manually and I want to remove it)
  • 我正在使用 SessionManagementFilter,我需要遠離它的指導(I am using SessionManagementFilter and I need guidance on moving away from that)
  • 我希望將身份驗證存儲在會話之外的其他內容中(I want to store the authentication in something other than the session)
  • 我正在使用無狀態身份驗證,但是我仍然希望將其存儲在會話中(I am using a stateless authentication, but I’d still like to store it in the session)
  • 我正在使用 SessionCreationPolicy.Never,但是應用程序仍然在創建會話。(I am using SessionCreationPolicy.NEVER but the application is still creating sessions.)

Understanding Session Management’s Components

會話管理支持由幾個組件組成,它們共同提供功能。

這些組件是 SecurityContextHolderFilterSecurityContextPersistenceFilterSessionManagementFilter

在 SpringSecurity6中,默認情況下不設置 SecurityContextPersisenceFilter 和 SessionManagementFilter。除此之外,任何應用程序都應該只設置 SecurityContextHolderFilter 或 SecurityContextPersisenceFilter,而不能同時設置兩者。

The SessionManagementFilter

SessionManagementFilter 根據 SecurityContextHolder 的當前內容檢查 SecurityContextRepository 的內容,以確定用戶在當前請求期間是否已被身份驗證,通常是通過非交互式身份驗證機制,如預先身份驗證或 remember-me [1]。如果存儲庫包含安全上下文,則filter不執行任何操作。如果沒有,并且線程本地的 SecurityContext 包含一個(非匿名的) Authentication 對象,則篩選器假定它們已經通過堆棧中以前的篩選器進行了身份驗證。然后它將調用配置的 SessionAuthenticationStrategy。

如果用戶當前沒有經過身份驗證,filter 將檢查是否請求了無效的會話 ID (例如,由于超時) ,并在設置了一個會話 ID 的情況下調用配置的 InvalidSessionStrategy。最常見的行為就是重定向到一個固定的 URL,這封裝在標準實現 SimpleRedirectInvalidSessionStrategy 中。如前所述,在通過命名空間配置無效的會話 URL 時也使用后者。

Moving Away From SessionManagementFilter

在 Spring Security 5中,默認配置依賴于 SessionManagementFilter 來檢測用戶是否剛剛通過身份驗證并調用 SessionAuthenticationStrategy。這樣做的問題在于,它意味著在典型的設置中,必須為每個請求讀取 HttpSession。

在 SpringSecurity6中,默認情況是身份驗證機制本身必須調用 SessionAuthenticationStrategy。這意味著不需要檢測身份驗證何時完成,因此不需要為每個請求讀取 HttpSession。

Things To Consider When Moving Away From SessionManagementFilter

在 Spring Security 6中,默認情況下不使用 SessionManagementFilter,因此,來自 sessionManagement DSL 的一些方法不會產生任何效果。

MethodReplacement
sessionAuthenticationErrorUrlConfigure an AuthenticationFailureHandler in your authentication mechanism
sessionAuthenticationFailureHandlerConfigure an AuthenticationFailureHandler in your authentication mechanism
sessionAuthenticationStrategyConfigure an SessionAuthenticationStrategy in your authentication mechanism as discussed above

如果嘗試使用這些方法中的任何一種,將引發異常。

Customizing Where the Authentication Is Stored

默認情況下,SpringSecurity 在 HTTP 會話中為您存儲安全上下文。然而,這里有幾個你可能需要自定義的原因:

  • 您可能希望在 HttpSessionSecurityContextRepository 實例上調用個別的setters
  • 您可能希望將安全上下文存儲在緩存或數據庫中,以啟用水平伸縮

首先,您需要創建 SecurityContextRepository 的實現,或者使用類似 HttpSessionSecurityContextRepository 的現有實現,然后您可以在 HttpSecurity 中設置它。

Customizing the SecurityContextRepository

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {SecurityContextRepository repo = new MyCustomSecurityContextRepository();http// ....securityContext((context) -> context.securityContextRepository(repo));return http.build();
}

上述配置設置 SecurityContextHolderFilter 上的 SecurityContextRepository 和參與身份驗證過濾器,如 UsernamePasswordAuthenticationFilter。要在無狀態篩選器中設置它,請參閱如何自定義 SecurityContextRepository for Statless Authentication。

如果使用自定義身份驗證機制,則可能希望自己存儲身份驗證。

Storing the Authentication manually

例如,在某些情況下,您可能需要手動驗證用戶,而不是依賴于 Spring Security filters。您可以使用自定義過濾器或 Spring MVC 控制器端點來完成這項工作。如果要在請求之間保存身份驗證,例如,在 HttpSession 中,必須這樣做:

private SecurityContextRepository securityContextRepository =new HttpSessionSecurityContextRepository(); // 1@PostMapping("/login")
public void login(@RequestBody LoginRequest loginRequest, HttpServletRequest request, HttpServletResponse response) { // 2UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated(loginRequest.getUsername(), loginRequest.getPassword()); // 3 Authentication authentication = authenticationManager.authenticate(token); // 4 SecurityContext context = securityContextHolderStrategy.createEmptyContext();context.setAuthentication(authentication); // 5securityContextHolderStrategy.setContext(context);securityContextRepository.saveContext(context, request, response); // 6
}class LoginRequest {private String username;private String password;// getters and setters
}
  1. 將 SecurityContextRepository 添加到控制器
  2. 注入 HttpServletRequest 和 HttpServletResponse 以保存 SecurityContext
  3. 使用提供的憑據創建未經身份驗證的 UsernamePasswordAuthenticationToken
  4. 調用 AuthenticationManager # authenticate 對用戶進行身份驗證
  5. 創建 SecurityContext 并在其中設置身份驗證
  6. 在 SecurityContextRepository 中保存 SecurityContext

就是這樣。如果您不確定上面示例中的 securityContextHolderStrategy 是什么,可以在使用 SecurityContextStrategy 部分了解更多信息。

Properly Clearing an Authentication

如果您正在使用 Spring Security 的 Logout Support,那么它將為您處理許多事情,包括清除和保存上下文。但是,假設您需要手動將用戶從應用程序中注銷。在這種情況下,您需要確保正確地清除和保存上下文。

Configuring Persistence for Stateless Authentication

例如,有時不需要創建和維護 HttpSession,以便跨請求持久化身份驗證。某些身份驗證機制(如 HTTPBasic)是無狀態的,因此會在每個請求上重新驗證用戶。

如果您不希望創建會話,可以使用 SessionCreationPolicy. STATELSS,如下所示:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http// ....sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));return http.build();
}

上述配置正在將 SecurityContextRepository 配置為使用 NullSecurityContextRepository,并且還阻止將請求保存到會話中。

如果您使用的是 SessionCreationPolicy. NEVER,您可能會注意到應用程序仍然在創建 HttpSession。在大多數情況下,發生這種情況是因為請求被保存在會話中,以便在身份驗證成功后再次請求經過身份驗證的資源。為了避免這種情況,請參考如何防止請求被保存 how to prevent the request of being saved 節。

Storing Stateless Authentication in the Session

如果出于某種原因,您正在使用無狀態身份驗證機制,但仍然希望在會話中存儲身份驗證,則可以使用 HttpSessionSecurityContextRepository 而不是 NullSecurityContextRepository。

對于 HTTP Basic,可以添加一個 ObjectPostProcessor,用于更改 BasicAuthenticationFilter 使用的 SecurityContextRepository:

Store HTTP Basic authentication in the HttpSession

@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {http// ....httpBasic((basic) -> basic.addObjectPostProcessor(new ObjectPostProcessor<BasicAuthenticationFilter>() {@Overridepublic <O extends BasicAuthenticationFilter> O postProcess(O filter) {filter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());return filter;}}));return http.build();
}

上述方法也適用于其他身份驗證機制,如承載令牌身份驗證。

在 Spring Security 5中,默認行為是使用 SecurityContextPersisenceFilter 將 SecurityContext 自動保存到 SecurityContextRepository。必須在提交 HttpServletResponse 之前和 SecurityContextPersisenceFilter 之前保存。不幸的是,SecurityContext 的自動持久化在請求完成之前(即在提交 HttpServletResponse 之前)完成時可能會讓用戶感到驚訝。跟蹤狀態以確定是否需要保存,從而導致有時不必要地寫入 SecurityContextRepository (即 HttpSession)也很復雜。

由于這些原因,不推薦使用 SecurityContextHolderFilter 替換 SecurityContextPersisenceFilter。在 Spring Security 6中,默認行為是 SecurityContextHolderFilter 將只從 SecurityContextRepository 讀取 SecurityContext 并在 SecurityContextHolder 中填充它。用戶現在必須使用 SecurityContextRepository 顯式地保存 SecurityContext,如果他們希望 SecurityContext 在請求之間保持的話。這樣可以消除模糊性,并在必要時只需要寫入 SecurityContextRepository (即 HttpSession) ,從而提高性能。

How it works

總而言之,如果 requireExplicitSave 為 true,Spring Security 將設置 SecurityContextHolderFilter 而不是 SecurityContextPersisenceFilter

Configuring Concurrent Session Control

如果您希望限制單個用戶登錄到您的應用程序的能力,Spring Security 通過以下簡單的添加支持開箱即用。首先,您需要將以下偵聽器添加到您的配置中,以保持 Spring Security 對會話生命周期事件的更新:

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {return new HttpSessionEventPublisher();
}

然后在安全配置中添加以下代碼行:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement(session -> session.maximumSessions(1));return http.build();
}

這將阻止用戶多次登錄——第二次登錄將導致第一次登錄失效。

使用 Spring Boot,您可以通過以下方式測試上面的配置場景:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MaximumSessionsTests {@Autowiredprivate MockMvc mvc;@Testvoid loginOnSecondLoginThenFirstSessionTerminated() throws Exception {MvcResult mvcResult = this.mvc.perform(formLogin()).andExpect(authenticated()).andReturn();MockHttpSession firstLoginSession = (MockHttpSession) mvcResult.getRequest().getSession();this.mvc.perform(get("/").session(firstLoginSession)).andExpect(authenticated());this.mvc.perform(formLogin()).andExpect(authenticated());// first session is terminated by second loginthis.mvc.perform(get("/").session(firstLoginSession)).andExpect(unauthenticated());}}

可以使用“最大會話”示例進行嘗試。

另外,通常您希望防止第二次登錄,在這種情況下,您可以使用:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement(session -> session.maximumSessions(1).maxSessionsPreventsLogin(true));return http.build();
}

第二次登錄將被拒絕。“拒絕”的意思是,如果使用的是基于表單的登錄,那么用戶將被發送到身份驗證-失敗-url。如果第二次身份驗證是通過另一種非交互機制進行的,比如“ remember-me”,那么將向客戶端發送一個“未授權”(401)錯誤。如果希望使用錯誤頁面,可以將屬性 session-entication-error-url 添加到session-management元素中。

使用 Spring Boot,您可以通過以下方式測試上述配置:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MaximumSessionsPreventLoginTests {@Autowiredprivate MockMvc mvc;@Testvoid loginOnSecondLoginThenPreventLogin() throws Exception {MvcResult mvcResult = this.mvc.perform(formLogin()).andExpect(authenticated()).andReturn();MockHttpSession firstLoginSession = (MockHttpSession) mvcResult.getRequest().getSession();this.mvc.perform(get("/").session(firstLoginSession)).andExpect(authenticated());// second login is preventedthis.mvc.perform(formLogin()).andExpect(unauthenticated());// first session is still validthis.mvc.perform(get("/").session(firstLoginSession)).andExpect(authenticated());}}

如果對基于表單的登錄使用自定義身份驗證filter,則必須顯式配置并發會話控制支持。您可以使用“最大會話防止登錄”示例嘗試使用它。

Detecting Timeouts

會話會自行到期,不需要做任何事情來確保刪除安全上下文。也就是說,SpringSecurity 可以檢測會話何時過期,并采取您指示的特定操作。例如,當用戶使用已過期的會話發出請求時,您可能希望重定向到特定的端點。這是通過 HttpSecurity 中的無效 SessionUrl 實現的:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement(session -> session.invalidSessionUrl("/invalidSession"));return http.build();
}

請注意,如果使用此機制檢測會話超時,則如果用戶注銷然后在沒有關閉瀏覽器的情況下重新登錄,則可能會錯誤地報告錯誤。這是因為當您使會話無效時,會話 cookie 不會被清除,即使用戶已經登出,它也會被重新提交。如果是這種情況,您可能需要配置注銷以清除會話 cookie。

Customizing the Invalid Session Strategy

ValidSessionUrl 是一種方便的方法,用于使用 SimpleRedirectInvalidSessionStrategy 實現設置 InvalidSessionStrategy。如果希望自定義行為,可以實現 InvalidSessionStrategy 接口,并使用 valididSessionStrategy 方法對其進行配置:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement(session -> session.invalidSessionStrategy(new MyCustomInvalidSessionStrategy()));return http.build();
}

Clearing Session Cookies on Logout

你可以在注銷時顯式地刪除這個 JSESSIONID cookie,例如在注銷處理程序中使用 Clear-Site-Data 頭:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.logout((logout) -> logout.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(COOKIES))));return http.build();
}

這樣做的好處是容器不可知,并且適用于任何支持 Clear-Site-Data 報頭的容器。

作為替代,您還可以在注銷處理程序中使用以下語法:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.logout(logout -> logout.deleteCookies("JSESSIONID"));return http.build();
}

不幸的是,這并不能保證在每個 servlet 容器中都能正常工作,因此您需要在您的環境中對其進行測試。

Understanding Session Fixation Attack Protection

會話固定攻擊是一種潛在的風險,惡意攻擊者可能通過訪問一個站點來創建一個會話,然后說服另一個用戶使用相同的會話登錄(例如,通過向他們發送一個包含會話標識符作為參數的鏈接)。SpringSecurity 通過創建新會話或在用戶登錄時更改會話 ID 來自動防止這種情況發生。

Configuring Session Fixation Protection

你可以通過選擇三個推薦的選項來控制會話固定保護策略:

  • ChangeSessionId-不要創建新的會話,而是使用 Servlet 容器(HttpServletRequest # changeSessionId ())提供的會話固定保護。此選項僅在 Servlet 3.1(JavaEE7)和更新的容器中可用。在舊容器中指定它將導致異常。這是 Servlet 3.1和更新的容器中的默認值。
  • NewSession-創建一個新的“ clean”會話,不復制現有的會話數據(仍將復制與 Spring Security 相關的屬性)。
  • MigateSession-創建一個新會話并將所有現有會話屬性復制到新會話。這是 Servlet 3.0或更老的容器中的默認值。

您可以通過以下方法配置會話固定保護:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement((session) -> session.sessionFixation((sessionFixation) -> sessionFixation.newSession()));return http.build();
}

當發生會話固定保護時,會導致在應用程序上下文中發布 SessionFixationProtectionEvent。

如果您使用 changeSessionId,這種保護也會導致任何 jakarta.servlet.http.HttpSessionIdListener 正在通知 ,因此如果您的代碼同時偵聽這兩個事件,請謹慎使用。

您還可以將會話固定保護設置為無,以禁用它,但是不建議這樣做,因為這會使您的應用程序容易受到攻擊。

Using SecurityContextHolderStrategy

考慮以下代碼塊:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
Authentication authentication = this.authenticationManager.authenticate(token);
// ...
SecurityContext context = SecurityContextHolder.createEmptyContext(); // 1
context.setAuthentication(authentication);// 2
SecurityContextHolder.setContext(context);// 3
  1. 通過靜態訪問 SecurityContextHolder 創建一個空的 SecurityContext 實例。
  2. 設置 SecurityContext 實例中的 Authentication 對象。
  3. 靜態設置 SecurityContextHolder 中的 SecurityContext 實例。

雖然上面的代碼工作得很好,但它可能會產生一些不想要的效果: 當組件通過 SecurityContextHolder 靜態訪問 SecurityContext 時,當有多個應用程序上下文需要指定 SecurityContextHolderStrategy 時,這可能會創建競態條件。這是因為在 SecurityContextHolder 中,每個類加載器有一個策略,而不是每個應用程序上下文有一個策略。

為了解決這個問題,組件可以從應用程序上下文連接 SecurityContextHolderStrategy。默認情況下,他們仍然會從 SecurityContextHolder 查找策略。

這些變化很大程度上是內部的,但是它們為應用程序提供了自動連接 SecurityContextHolderStrategy 而不是靜態訪問 SecurityContext 的機會。為此,應將代碼更改為:

public class SomeClass {private final SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();public void someMethod() {UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated(loginRequest.getUsername(), loginRequest.getPassword());Authentication authentication = this.authenticationManager.authenticate(token);// ...SecurityContext context = this.securityContextHolderStrategy.createEmptyContext(); // 1context.setAuthentication(authentication);// 2this.securityContextHolderStrategy.setContext(context);// 3}}
  1. 使用配置的 SecurityContextHolderStrategy 創建一個空的 SecurityContext 實例。
  2. 設置 SecurityContext 實例中的 Authentication 對象。
  3. 設置 SecurityContextHolderStrategy 中的 SecurityContext 實例。

Forcing Eager Session Creation

有時,急切地創建會話可能很有價值。這可以通過使用 ForceEagerSessionCreationFilter 完成,該過濾器可以使用以下方式配置:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));return http.build();
}

延伸閱讀

使用 Spring Session的集群Seession

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/38173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/38173.shtml
英文地址,請注明出處:http://en.pswp.cn/web/38173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

手機歌曲怎么轉換成mp3格式,手機電腦都能輕松搞定

不同的手機和音樂應用可能支持不同的音頻格式&#xff0c;而MP3作為一種廣泛兼容的音頻格式&#xff0c;因其體積小、音質相對較好的特點&#xff0c;至今仍被廣泛使用。 如果您想將手機中的歌曲轉換成MP3格式&#xff0c;以便于在更多設備上播放或節省存儲空間&#xff0c;本…

iOS端授權頁添加自定義按鈕

如何添加自定義控件 基于一鍵登錄的拉起授權頁面功能&#xff0c;如果想要在我們的授權頁面中添加自定義組件&#xff0c;例如使用其他方式登錄的按鈕&#xff0c;來實現其他方式登錄功能&#xff0c;為用戶呈現更多選擇登錄的方式。本文介紹如何在一鍵登錄授權界面中實現添加…

機器學習之監督學習

整理一下機器學習中監督學習相關內容&#xff0c;爭取梳理出一條易于理解和掌握的脈絡。下面會有很多相關參考博客和文章&#xff0c;先放到一起&#xff0c;最后再做個整體的梳理。持續更新中。。。。。。 監督學習作為機器學習的核心分支&#xff0c;其理論體系與實踐應用都…

C# 警告 warning MSB3884: 無法找到規則集文件“MinimumRecommendedRules.ruleset”

警告 warning MSB3884: 無法找到規則集文件“MinimumRecommendedRules.ruleset” C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Microsoft.CSharp.CurrentVersion.targets(129,9): warning MSB3884: 無法找到規則集文件“MinimumRe…

競賽選題 python的搜索引擎系統設計與實現

0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系統設計與實現 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;3分工作量&#xff1a;5分創新點&#xff1a;3分 該項目較為新穎&#xff…

正則表達式在Java中的應用與實例

正則表達式在Java中的應用與實例 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 正則表達式是一種強大的工具&#xff0c;用于模式匹配和字符串處理。在Java中…

武漢星起航:成功掛牌上股交,引領跨境電商行業進入全新發展階段

2023年10月30日&#xff0c;武漢星起航電子商務有限公司在上海股權托管交易中心成功掛牌展示&#xff0c;這一里程碑式的事件標志著武漢星起航正式登陸資本市場&#xff0c;開啟了公司發展的新篇章。作為亞馬遜跨境電商領域的領軍企業之一&#xff0c;武漢星起航此次掛牌不僅是…

文件操作詳解(C語言)

1.為什么要用到文件&#xff1f;怎樣數據才能持久化&#xff1f; 保存在內存中的數不安全&#xff08;一次斷電&#xff0c;忘記保存&#xff0c;不用了還給系統&#xff09; 持久化&#xff1a;保存在硬盤上&#xff08;放在文件中&#xff09; 什么是文件&#xff1f;文件…

Hadoop-08-HDFS集群 基礎知識 命令行上機實操 hadoop fs 分布式文件系統 讀寫原理 讀流程與寫流程 基本語法上傳下載拷貝移動文件

章節內容 上一節完成&#xff1a; HDFS的簡介內容HDFS基礎原理HDFS讀文件流程HDFS寫文件流程 背景介紹 這里是三臺公網云服務器&#xff0c;每臺 2C4G&#xff0c;搭建一個Hadoop的學習環境&#xff0c;供我學習。 之前已經在 VM 虛擬機上搭建過一次&#xff0c;但是沒留下…

SpringSecurity的執行原理

SpringSecurity的執行原理&#xff1a;當我們服務端接收到請求后&#xff0c;首先通過DelegatingFilterProxy代理對象交互&#xff0c;轉發給springsecurity的執行鏈&#xff0c;由于他自帶的執行鏈有16條&#xff0c;我們將不用的過濾器進行了排除&#xff0c;同時加入了我們自…

如何保護應用?可快速部署的WAF服務器分享

Web應用攻擊是安全事件和數據泄露的主要原因。相關統計表明&#xff0c;超過四分之三的網絡犯罪直指應用及其漏洞。為保護數量日益增長的應用安全&#xff0c;Web應用防火墻(WAF)因此而生。本文則聚焦于WAF服務器&#xff0c;了解它的性能與具體的實踐應用。   新加坡網絡安全…

《單片機》期末考試復習-學習筆記總結

題型 問答題(15分)編程題(65分)編程題1(20分)編程題2(45分)設計題(20分)一、問答題 1.1.單片機概念和特點 1.2. 51單片機的中斷結構 1.3.主從式多機通訊的概念及其工作原理 多機通信是指兩臺以上計算機之間的數據傳輸,主從式多機通信是多機通信系統中最簡單的一種,…

PHP電商系統開發指南最佳實踐

電子商務系統開發的最佳實踐包括&#xff1a;數據庫設計&#xff1a;選擇適合關系型數據庫&#xff0c;優化數據結構&#xff0c;考慮表分區&#xff1b;安全&#xff1a;加密數據&#xff0c;防止 sql 注入&#xff0c;處理會話管理&#xff1b;用戶界面&#xff1a;遵循 ux 原…

vue3長列表優化,使用vue-virtual-scroller實現直播間彈幕列表虛擬滾動效果

使用的組件庫是&#xff1a;https://github.com/Akryum/vue-virtual-scroller 官方文檔&#xff1a;vue-virtual-scroller 安裝依賴 npm install --save vue-virtual-scrollernextpnpm install --save vue-virtual-scrollernextyarn add vue-virtual-scrollernext 組件導入…

如何用文章改寫ai軟件進行改寫?5個軟件教你快速進行修改文章

如何用文章改寫ai軟件進行改寫&#xff1f;5個軟件教你快速進行修改文章 使用AI改寫軟件可以幫助你快速重寫文章&#xff0c;使其更加流暢、符合要求或避免重復。以下是五款優質的AI改寫軟件&#xff0c;它們能夠幫助你快速進行文章修改&#xff1a; 聰明靈犀 這是一款非常簡…

數據結構_1.0

一、數據結構概述 1.1 概念 在計算機科學中&#xff0c;數據結構是一種數據組織、管理和存儲的格式 。它是相互之間存在一種或多種特定關系的數據元素的集合。通常情況下&#xff0c;精心選擇的數據結構可以帶來更高的運行或者存儲效率。數據結構往往同高效的檢索算法和索引技…

【開源合規】開源許可證基礎知識與風險場景引入

文章目錄 什么是開源許可證(License)?開源許可證有什么用?開源許可證分類開源許可證分類及描述公共代碼 (Public Domain)CC0無License寬松型許可證 (Permissive)MITApache 2.0BSD弱互惠型許可證 (Weak Copyleft)LGPLMPLEPL互惠型許可證 (Reciprocal)GPLEUPL強互惠許可證 (Str…

讀-改-寫操作

1 什么是讀-改-寫操作 “讀-改-寫”&#xff08;Read-Modify-Write&#xff0c;簡稱RMW&#xff09;是一種常見的操作模式&#xff0c;它通常用于需要更新數據的場景。 這個模式包含三個基本步驟&#xff1a; 1.讀&#xff08;Read&#xff09;&#xff1a;首先讀取當前的數據…

從0開始學習pyspark--pyspark的數據分析方式[第2節]

PySpark是Apache Spark的Python API&#xff0c;能夠在分布式計算環境中處理大規模數據。本文將詳細介紹PySpark中不同的數據分析方式&#xff0c;包括它們的使用場景、操作解釋以及示例代碼。 1. RDD&#xff08;Resilient Distributed Dataset&#xff09;API 概述 RDD是Sp…

Linux——查找文件-find(詳細)

查找文件-find 作用 - 按照文件名、大小、時間、權限、類型、所屬者、所屬組來搜索文件 格式 find 查找路徑 查找條件 具體條件 操作 注意 - find命令默認的操作是print輸出 - find是檢索文件的&#xff0c;grep是過濾文件中字符串 參數 參數 …