<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
筆者使用 Spring Security 5.8 時,發現網上很多教學所教的 Spring Security 設定類 SecurityConfig.java
的設定風格還是停留在繼承 WebSecurityConfigurerAdapter
的風格。然而, WebSecurityConfigurerAdapter
在 Spring Security 5.7.0-M2 版本中已經被 deprecated 了。因此在本文中分享 Spring 官方最新推薦的 Spring Security 設定風格。
在 Spring Security 5.7.0 (2022 年 2 月 21 日更新) 中,官方棄用了 WebSecurityConfigurerAdapter
。因為Spring 官方鼓勵開發者朝著元件化安全設定遷移。為了幫助開發者順利過渡到這種設定風格,Spring 官方準備了一系列常見的使用案例和建議的替代方案。
在下面的例子中,我們將遵循最佳實踐,使用 Spring Security lambda DSL 和 HttpSecurity.java
中的 authorizeHttpRequests()
方法來定義授權規則。如果您對 lambda DSL 感到陌生,可以參考我的這篇文章進行學習:《如何使用Lambda DSL設定Spring Security》。
在 Spring Security 5.4 中,新增了通過建立一個 SecurityFilterChain
的 Bean 來設定 HttpSecurity
的功能。
首先來看看沒有棄用 WebSecurityConfigurerAdapter
的範例,下面是使用 WebSecurityConfigurerAdapter
的設定範例,該設定使用 httpBasic()
方法來保護所有的介面。
@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authz) -> authz .anyRequest().authenticated() ) .httpBasic(withDefaults()); } }
但今後, WebSecurityConfigurerAdapter
就被 Spring 官方棄用了,取而代之的是通過註冊一個 SecurityFilterChain
的 Bean 來設定 HttpSecurity
。
@Configuration public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authz) -> authz .anyRequest().authenticated() ) .httpBasic(withDefaults()); return http.build(); } }
在 Spring Security 5.4 中,Spring 官方新增了 WebSecurityCustomizer
。
WebSecurityCustomizer
是一個回撥介面,可以用來設定 WebSecurity
。
首先來看看先前的舊設定風格的程式碼範例:使用 WebSecurityConfigurerAdapter
來忽略與 /ignore1
或 /ignore2
匹配的請求 (即不攔截這兩個請求進行認證授權) 。
@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/ignore1", "/ignore2"); } }
但今後,Spring 官方不再推薦上面的設定風格,取而代之的是向 Spring 容器中注入一個 WebSecurityCustomizer
的 Bean 。
@Configuration public class SecurityConfiguration { @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2"); } }
注意:如果你想通過設定 WebSecurity
來忽略請求,建議優先考慮通過設定 HttpSecurity
的 authorizeHttpRequests()
方法,使用 .permitAll()
來實現。
LDAP (Light Directory Access Protocol) ,是基於 X.500 標準的輕量級目錄存取協定。有興趣的同學可以自行谷歌搜尋學習,LDAP 這種協定常用於授權認證的情景。
在 Spring Security 5.7 中,Spring 官方新增了 EmbeddedLdapServerContextSourceFactoryBean
、LdapBindAuthenticationManagerFactory
和 LdapPasswordComparisonAuthenticationManagerFactory
,用來建立一個嵌入式 LDAP 伺服器和一個 AuthenticationManager
物件,來執行 LDAP 認證。
同樣的,先來看先前舊的設定風格的範例,繼承 WebSecurityConfigurerAdapter
,建立一個嵌入式 LDAP 伺服器,建立一個 AuthenticationManager
,使用繫結認證 (Bind Authentication) 來執行 LDAP 認證。
@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .ladpAuthentication() .userDetailsContextMapper(new PersonContextMapper()) .userDnPatterns("uid={0}, ou=people") .contextSource() .port(0); } }
但今後,Spring 官方不再推薦上面的設定風格,取而代之的是使用新的 LDAP 類。
@Configuration public class SecurityConfiguration { @Bean public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() { EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer(); contextSourceFactoryBean.setPort(0); return contextSourceFactoryBean; } @Bean AuthenticationManager ldapAuthenticationManager( BaseLdapPathContextSource contextSource) { LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource); factory.setUserDnPatterns("uid={0}, ou=people"); factory.setUserDetailsContextMapper(new PersonContextMapper()); return factory.createAuthenticationManager(); } }
同樣的,先來看先前舊的設定風格的範例,繼承 WebSecurityConfigurerAdapter
,使用一個以預設方式初始化且具有一個使用者的嵌入式 DataSource
。
@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .build(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); auth.jdbcAuthentication() .withDefaultSchema() .dataSource(dataSource()) .withUser(user); } }
但今後,Spring 官方不再推薦上面的設定風格,取而代之的是向 Spring 容器注入一個 JdbcUserDetailsManager
的 Bean 。
@Configuration public class SecurityConfiguration { @Bean public DataSource datasource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION) .build(); } @Bean public UserDetailsManager users(DataSource dataSource) { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource); users.createUser(user); return users; } }
注意:上面的程式碼範例第 14 行中,為了密碼的可讀性才使用方法 User.withDefaultPasswordEncoder()
。在實際的生產環境中並不會使用預設的密碼編碼器,因為這樣儲存的密碼是明文,十分不安全。這裡推薦使用 BCryptPasswordEncoder 作為密碼編碼器來對密碼進行加密成暗文儲存。
與上面儲存在資料庫的不同,In-Memory 是把使用者資訊儲存在記憶體中。
同樣的,先來看先前舊的設定風格的範例,繼承 WebSecurityConfigurerAdapter
來設定儲存在記憶體中的一個使用者資訊。
@Configuration public class SecurityConfiguration extends WebSecutiryConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); auth.inMemoryAuthentication() .withUser(user); } }
但今後,Spring 官方不再推薦上面的設定風格,取而代之的是向 Spring 容器注入一個 InMemoryUserDetailsManager
的 Bean 。
@Configuration public class SecurityConfiguration { @Bean public InMemoryUserDetailsManager userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }
注意:上面的程式碼範例第 6 行中,為了密碼的可讀性才使用方法 User.withDefaultPasswordEncoder()
。在實際的生產環境中並不會使用預設的密碼編碼器,因為這樣儲存的密碼是明文,十分不安全。這裡推薦使用 BCryptPasswordEncoder 作為密碼編碼器來對密碼進行加密成暗文儲存。
如果你想要建立整個應用都可以呼叫的 AuthenticationManager
物件,只需要簡單地使用註解 @Bean
來注入 Spring 容器。
設定風格範例與 LDAP 的設定範例相同。
在 Spring Security 5.6 中,Spring 官方在 HttpSecurity
中新增了方法 authenticationManager()
,該方法重寫具體的 SecurityFilterChain
的預設 AuthenticationManager
。
下面是設定自定義區域性 AuthenticationManager
的程式碼範例。
@Configuration public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authz) -> authz .anyRequest().authticated()) .httpBasic(withDefaults()) .authenticationManager(new CustomAuthenticationManager()); return http.build(); } }
可以使用 custom DSL 來呼叫區域性 AuthenticationManager
。這實際上正是 Spring Security 內部實現諸如 HttpSecurity.authorizeRequests()
方法的方式。
public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> { @Override public void configure(HttpSecurity http) throws Exception { AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); http.addFilter(new CustomFilter(authenticationManager)); } public static MyCustomDsl customDsl() { return new MyCustomDsl(); } }
當Spring Security開始構建 SecurityFilterChain
時,custom DSL 就會被自動呼叫。
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // ... http.apply(customDsl()); return http.build(); }
到此這篇關於Spring Security設定保姆級教學的文章就介紹到這了,更多相關Spring Security設定內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45