一文詳解Spring Security的基本用法
Spring Security
是一個功能強大且高度可定制的身份驗證和訪問控制框架, 提供瞭完善的認證機制和方法級的授權功能。是一款非常優秀的權限管理框架。它的核心是一組過濾器鏈,不同的功能經由不同的過濾器。 今天通過一個簡單的案例瞭解一下Spring Security
的基本用法
1.引入依賴
在項目中引入Spring Security
依賴,代碼如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
引入依賴後,整個項目都被Spring Security
保護起來,所有的接口都要登錄之後才能訪問瞭,例如,我需要訪問/doc.html
接口文檔,直接跳到登錄頁面。如下圖:
這時,你會有十萬個為什麼啦?這個頁面哪裡的?這個用戶名和密碼是啥?等等。不著急,聽我一一道來。
2.用戶名和密碼在哪裡設置
當我們引入瞭Spring Secruity依賴後,啟動項目之後,密碼就會在控制臺中輸出的,格式是UUID,每一次啟動密碼都不一樣的,而用戶名是默認是User的。
Using generated security password: 8b2d752b-8892-4cd3-a7a9-a36e79e1cad8
我們可以通過項目的配置文件自定義用戶名和密碼的,代碼如下,這樣每次重啟項目,用戶名和密碼都是固定不變的。
spring: security: user: name: didiplus password: didiplus
3.UserDetailsService接口詳解
UserDetailsService
接口隻有一個抽象方法就是loadUserByUsername(String username)
。代碼如下:
public interface UserDetailsService { UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; }
UserDetailsService
接口的返回值是UserDetails
接口, 這又是一個接口,Spring Security
框架提供瞭它的實現類org.springframework.security.core.userdetails
包下的User類對象 。userdetails
源碼如下:
Spring Security
提供瞭三個UserDetailsService
接口的實現類,分別是CachingUserDetailsService
,JdbcDaoImpl
,InMemoryUserDetailsManager
3.1JdbcDaoImpl實現類
該實現類是通過數據庫獲取用戶名和密碼,JdbcUserDetailsManager
中定義瞭一大堆SQL語句,如下:
接著我們在看一下JdbcDaoImpl
中的loadUsersByUsername
方法,如下:
3.2InMemoryUserDetailsManager實現類
以上代碼是判斷內存中的HashMap
集合中是否有用戶數據對應的User對象,如果沒有,直接拋出異常,如果有就返回該用戶的User對象信息。
以上代碼是把配置文件中的User
相關信息讀取到。通過分析源碼發現 Spring Security
框架完成用戶登錄認證的核心就在與org.springframework.security.core.userdetails
包下的UserDetailsService
接口。
3.3自定義實現類實現UserDetailsService接口
自定義實現類MyUserDetailsServiceImpl,代碼如下:
@Service public class MyUserDetailsServiceImpl implements UserDetailsService { private static final String USERNAME="admin"; private static final String PASSWORD="admin123"; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if (!USERNAME.equals(username)){ throw new UsernameNotFoundException("用戶名不存在"); } UserDetails userDetails = new User(USERNAME,PASSWORD, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,common")); return userDetails; } }
重啟項目看看,輸入定義的用戶名和密碼,發現登錄不瞭,查看控制臺發現報錯,提示如下:
報錯的原因是沒有使用任何的PasswordEncoder
,我們輸入的密碼沒有用加密工具進行加密 。 Spring Security
其實已經給我們提供瞭很多的PasswordEncoder
。 在org.springframework.security.crypto.password
包下有一個PasswordEncoder
接口,看看他的實現類
把這個PasswordEncoder的任意一個我們需要用來加密密碼的實現類的Bean註入到容器裡面,就可以直接拿來使用 ,代碼如下:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } }
修改MyUserDetailsServiceImpl
類如下:
@Service public class MyUserDetailsServiceImpl implements UserDetailsService { private static final String USERNAME="admin"; private static final String PASSWORD="admin123"; @Resource BCryptPasswordEncoder cryptPasswordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if (!USERNAME.equals(username)){ throw new UsernameNotFoundException("用戶名不存在"); } UserDetails userDetails = new User(USERNAME,cryptPasswordEncoder.encode(PASSWORD), AuthorityUtils.commaSeparatedStringToAuthorityList("admin,common")); return userDetails; } }
重啟項目再次測試,輸入定義的賬號和密碼。即可訪問到接口文檔頁面。
4.如何修改登錄頁面
覺得默認的登錄頁面很醜,我們如何定義自己的登錄頁面呢?方法也很簡單,首先我們先去準備一個登錄頁面。如下:
前端代碼如下:
<form action="/login" class="login-form" > <h1>登錄</h1> <div class="txtb"> <input type="text" name="user"> <span data-placeholder="Username"></span> </div> <div class="txtb"> <input type="password" name="pass"> <span data-placeholder="Password"></span> </div> <input type="submit" class="logbtn" value="登錄"> <div class="bottom-text"> Don't have account? <a href="#" rel="external nofollow" >Sign up</a> </div> </form>
把登錄頁面文件存放到項目的資源文件夾中static
目錄下,然後在SecurityConfig
重寫configure(HttpSecurity http)
這個方法,代碼如下:
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/login.html") #自定義登錄頁面 .usernameParameter("user") #對應前端表達name屬性 .passwordParameter("pass") #對應前端表達name屬性 .loginProcessingUrl("/login") .defaultSuccessUrl("/doc.html") #登錄成功後跳轉的頁面地址 .failureUrl("/login?error=true") .and() .authorizeRequests() .antMatchers("/login.html").permitAll() #放通登錄頁面 .anyRequest().authenticated(); #其他請求都要認證 http.csrf().disable(); }
重新啟動項目,輸入定義的用戶名和密碼,登錄成功直接跳轉到/doc.html
。
antMatchers("url").permitAll() 是把某個url放通,不需要登錄就能訪問。
到此這篇關於一文詳解Spring Security的基本用法的文章就介紹到這瞭,更多相關Spring Security用法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring Security密碼解析器PasswordEncoder自定義登錄邏輯
- Spring boot整合security詳解
- 關於SpringSecurity配置403權限訪問頁面的完整代碼
- Spring Security使用數據庫登錄認證授權
- SpringSecurity從數據庫中獲取用戶信息進行驗證的案例詳解