Spring boot整合security詳解
前言
在進行框架選型時最常用的選擇就是在Spring security 和Shiro中進行抉擇,Spring security 和 shiro 一樣,都具有認證、授權(quán)、加密等用于權(quán)限管理的功能。但是對于Springboot而言,Spring Security比Shiro更合適一些,他們都是Spring生態(tài)里的內(nèi)容,并且在使用上Spring boot只需要引入Security就可以實現(xiàn)基礎(chǔ)的登陸驗證。
配置依賴
spring boot的依賴版本:2.7.1
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.1</version> <relativePath/> </parent>
添加Security的依賴版本為:2.6.7
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.6.7</version> </dependency>
這樣就簡單集成了security了,現(xiàn)在啟動項目進行訪問會直接有了登陸頁面
這個是security進行了簡單登陸的實現(xiàn),官方提供的默認賬號是user,密碼會在啟動命令臺里打印,下圖中的即是密碼
這個密碼每次啟動都會隨機生成,也可以在配置文件中進行指定,在配置文件中加入一下代碼
spring:
security:
user:
name: admin
password: 123456
roles: admin
再重啟項目,此時的賬號密碼就是設(shè)置的這個了,當(dāng)然光這樣做肯定不滿足我們的權(quán)限需求,下面實現(xiàn)我們的具體權(quán)限配置
用戶配置
? 要實現(xiàn)自定義配置,首先創(chuàng)建一個繼承于WebSecurityConfigurerAdapter的配置類,并且實現(xiàn)configure方法,這個方法里就是自定義實現(xiàn)權(quán)限的邏輯
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { } }
@EnableWebSecurity注解,這個注解是Spring Security用于啟用web安全的注解。
? Spring Security的配置用戶存儲地址有四種實現(xiàn)方式
- 內(nèi)存用戶存儲
- 數(shù)據(jù)庫用戶存儲
- LDAP用戶存儲
- 自定義用戶存儲
1.內(nèi)存用戶存儲
這個存儲方式就是寫死在程序了,啟動的時候初始化好了用戶權(quán)限的集合,優(yōu)點是很快,因為基于內(nèi)存,缺點是不靈活、無法動態(tài)更改權(quán)限、不可以進行注冊操作,所以我們基本不用這種方式。
重寫configure方法后啟動查看效果,在登陸頁面可以通過這兩個賬號進行登陸就完成了
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()) .withUser("admin").password(passwordEncoder().encode("123456")).authorities("ADMIN") .and() .withUser("anduoduo").password(passwordEncoder().encode("123456")).authorities("ORDINARY"); } private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
2.數(shù)據(jù)庫用戶存儲
用戶權(quán)限放在數(shù)據(jù)庫中是我們最常用的方式,這樣可以讓我們可以很方便地對用戶信息進行增刪改查。并且還可以為用戶添加除認證信息外的附加信息。
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private DataSource dataSource; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder()) .usersByUsernameQuery( "select username, password, status from Users where username = ?") .authoritiesByUsernameQuery( "select username, authority from Authority where username = ?"); } private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
auth調(diào)用jdbcAuthentication()來告訴Spring Security使用jdbc的方式來查詢用戶和權(quán)限,dataSource()方法指定數(shù)據(jù)庫連接信息,passwordEncoder()指定密碼加密規(guī)則,用戶的密碼數(shù)據(jù)應(yīng)該以同樣的方式進行加密存儲,不然,兩個加密方式不同的密碼,匹配補上。usersByUsernameQuery()和authoritiesByUsernameQuery()方法分別定義了查詢用戶和權(quán)限信息的sql語句。
3.LDAP用戶存儲
這種方式很少見應(yīng)該,LDAP是一個文件協(xié)議,這種方式就是通過獲取文件來做權(quán)限內(nèi)容,之前l(fā)og4j出現(xiàn)的被侵入bug就是因為這一部分,可以通過LDAP進行代碼執(zhí)行。
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> configurer = auth.ldapAuthentication() .userSearchBase("ou=people") .userSearchFilter("(uid={0})") .groupSearchBase("ou=groups") .groupSearchFilter("member={0}"); configurer.passwordCompare() .passwordEncoder(passwordEncoder()) .passwordAttribute("passcode"); configurer.contextSource().url("ldap://xxxxx.com:17099/dc=xxxxxx,dc=com"); } private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
4.自定義用戶存儲
? 自定義用戶存儲,就是自行使用認證名稱來查找對應(yīng)的用戶數(shù)據(jù),然后交給Spring Security使用。這種方式需要一個實現(xiàn)UserDetailsService的service類,
public class UserServiceImpl implements UserDetailsService { @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userMapper.getUserByUsername(username); return user == null ? new User() : user; } }
這個實現(xiàn)類只需要實現(xiàn)一個方法:loadUserByUsername()。該方法需要做的是使用傳過來的username來匹配一個帶有密碼等信息的用戶實體。User的實體類需要實現(xiàn)UserDetails,因為返回對象是UserDetails,也就是說,查到的信息里,必須得有Spring Security所需要的信息。
public class User implements UserDetails { @Override public Collection<? extends GrantedAuthority> getAuthorities() { return null; } @Override public String getPassword() { return null; } @Override public String getUsername() { return null; } @Override public boolean isAccountNonExpired() { return false; } @Override public boolean isAccountNonLocked() { return false; } @Override public boolean isCredentialsNonExpired() { return false; } @Override public boolean isEnabled() { return false; } }
config代碼
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } @Bean private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
這個配置只需要告訴Spring Security的UserDetailsService實現(xiàn)類是哪個就可以了,它會去調(diào)用loadUserByUsername()來查找用戶。
攔截配置
攔截也是同樣在SecurityConfig配置類里的configure方法,只不過重載了configure方法
// 配置安全策略 @Override protected void configure(HttpSecurity http) throws Exception { // 設(shè)置路徑及要求的權(quán)限,支持 ant 風(fēng)格路徑寫法 http.authorizeRequests() // 設(shè)置 OPTIONS 嘗試請求直接通過 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers("/api/demo/user").hasAnyRole("user", "admin") // 注意使用 hasAnyAuthority 角色需要以 ROLE_ 開頭 .antMatchers("/api/demo/admin").hasAnyAuthority("ROLE_admin") .antMatchers("/api/demo/hello").permitAll() .and() // 開啟表單登錄 .formLogin().permitAll() .and() // 開啟注銷 .logout().permitAll(); }
到此這篇關(guān)于Spring boot整合security詳解的文章就介紹到這了,更多相關(guān)Spring boot security內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot淺析安全管理之基于數(shù)據(jù)庫認證
- SpringBoot淺析安全管理之OAuth2框架
- SpringBoot淺析安全管理之Shiro框架
- SpringBoot2.0 整合 SpringSecurity 框架實現(xiàn)用戶權(quán)限安全管理方法
- SpringBoot+SpringSecurity+jwt實現(xiàn)驗證
- SpringBoot整合SpringSecurity實現(xiàn)JWT認證的項目實踐
- Springboot詳解整合SpringSecurity實現(xiàn)全過程
- SpringBoot整合Security安全框架實現(xiàn)控制權(quán)限
- SpringBoot淺析安全管理之Spring Security配置
相關(guān)文章
jstack報錯Unable to open socket file解決
這篇文章主要為大家介紹了jstack報錯Unable to open socket file的解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-02-02java 多線程Thread與runnable的區(qū)別
這篇文章主要介紹了java 多線程Thread與runnable的區(qū)別的相關(guān)資料,java線程有兩種方法繼承thread類與實現(xiàn)runnable接口,下面就提供實例幫助大家理解,需要的朋友可以參考下2017-08-08Java中的ScheduledThreadPoolExecutor定時任務(wù)詳解
這篇文章主要介紹了Java中的ScheduledThreadPoolExecutor詳解,??ScheduledThreadPoolExecutor?繼承自?ThreadPoolExecutor,它主要用來在給定的延遲之后運行任務(wù),或者定期執(zhí)行任務(wù),ScheduledThreadPoolExecutor?的功能與?Timer?類似<BR>,需要的朋友可以參考下2023-12-12Java實現(xiàn)反轉(zhuǎn)一個鏈表的示例代碼
本文主要介紹了Java實現(xiàn)反轉(zhuǎn)一個鏈表的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07springboot構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢的方法
本文主要介紹了springboot怎樣構(gòu)造樹形結(jié)構(gòu)數(shù)據(jù)并查詢,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11