詳解springSecurity之java配置篇
一 前言
本篇是springSecurity知識(shí)的入門第二篇,主要內(nèi)容是如何使用java配置的方式進(jìn)行配置springSeciruty,然后通過一個(gè)簡單的示例自定義登陸頁面,覆蓋原有springSecurity默認(rèn)的登陸頁面;學(xué)習(xí)這篇的基礎(chǔ)是 知識(shí)追尋者之前發(fā)布 過 的《springSecurity入門篇》
二 java配置
2.1配置賬號(hào)密碼
如下所示, 使用 @EnableWebSecurity
在配置類上開啟security配置功能; 在配置類中定義bean 名為 UserDetailsService
, 主要是 負(fù)責(zé) 設(shè)置賬號(hào)密碼,攔截URL,校驗(yàn)成功后重定向至URL;如果要使用多用戶,使用 manager.createUser
方法即可;
/** * @Author lsc * <p> </p> */ @EnableWebSecurity// 開啟springSecurity public class WebSecurityConfig { /* * * @Author lsc * <p> 主要是讓SpringSecurity知道springSecurityFilterChain負(fù)責(zé)管理應(yīng)用的URL * 校驗(yàn),通過賬號(hào),密碼的方式校驗(yàn)成功后重定向至應(yīng)用; * </p> * @Param [] */ @Bean public UserDetailsService userDetailsService() throws Exception { // User.UserBuilder users = User.withDefaultPasswordEncoder(); InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(users.username("user").password("user").roles("USER").build()); manager.createUser(users.username("admin").password("admin").roles("USER","ADMIN").build()); return manager; } }
訪問 localhost:8080/login 此時(shí)輸入的密碼就是 user , user ; 或者 admin, admin;
2.2 默認(rèn)授權(quán)配置
如下所示 往配置類中 添加 配置類,其 繼承 WebSecurityConfigurerAdapter, 重寫 configure(HttpSecurity http) 方法, 此方便的作用就是Security 的授權(quán)過程,如下示例中,任何的請求都需要認(rèn)證才可以訪問,并且登陸頁面還是security自帶的登陸頁面;
@Configuration public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests(authorize -> authorize // 授權(quán) .anyRequest() // 任何請求 .authenticated() // 認(rèn)證認(rèn)證 ) .formLogin(withDefaults()); // } }
2.3 過濾器順序
再向配置中添加如下配置,其內(nèi)容和上節(jié)內(nèi)容差不多,但是 攔截的url 是 以/api
為開頭的URL, 并且 是 ADMIN 角色才擁有訪問權(quán)限; 使用@Order(1)
, 過濾器配置會(huì)優(yōu)先走著條配置,其次才是上節(jié) 的配置;
@Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/**") .authorizeRequests(authorize -> authorize .anyRequest().hasRole("ADMIN") ) .httpBasic(withDefaults()) .formLogin(withDefaults()); } }
控制層添加代碼如下
@GetMapping("api/login") public String login(){ return "login"; }
首先使用user用戶訪問 http://localhost:8080/api/login 賬號(hào)密碼校驗(yàn)成功后跳轉(zhuǎn)應(yīng)用請求url, 出現(xiàn)禁止頁面,原因是user沒有ADMIN角色權(quán)限;
然后使用admin用戶登陸訪問 http://localhost:8080/api/login 賬號(hào)密碼校驗(yàn)成功后跳轉(zhuǎn)應(yīng)用請求url 正常放問;
登陸頁面如下
登陸成功后跳轉(zhuǎn)如下
三 自定義登陸頁面
3.1 實(shí)現(xiàn)自定頁面登陸
自定義登陸頁面 知識(shí)追尋者這邊需要引入引擎模板依賴 , thymeleaf; application配置如下
spring: # 引擎模板配置 thymeleaf: cache: false # 關(guān)閉緩存 mode: HTML prefix: classpath:/templates/ # 指定 thymeleaf 模板路徑 encoding: UTF-8 # 指定字符集編碼 mvc: static-path-pattern: /static/** # js ,css 等靜態(tài)文件路徑
然后在templates 下新建 login.html , 內(nèi)容如下
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"> <head> <title>Please Log In</title> </head> <body> <h1>Please Log In</h1> <div th:if="${param.error}"> Invalid username and password.</div> <div th:if="${param.logout}"> You have been logged out.</div> <form th:action="@{/login}" method="post"> <div> <input type="text" name="username" placeholder="Username"/> </div> <div> <input type="password" name="password" placeholder="Password"/> </div> <input type="submit" value="Log in" /> </form> </body> </html>
springSecurity授權(quán)配置內(nèi)容如下,如下所示,loginPage 配置登陸頁面,注意不要帶上.html,loginProcessingUrl 配置登陸url,注意這邊的url要與 login.html里面的action的url一致,否則會(huì)報(bào)錯(cuò);后面就是successForwardUrl 登陸成功后的轉(zhuǎn)發(fā),當(dāng)然還有登陸失敗的轉(zhuǎn)發(fā)failureForwardUrl()
, 讀者按需配置即可;
@Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/**") .authorizeRequests(authorize -> authorize .anyRequest().hasRole("USER") ) .formLogin(form -> { form .loginPage("/login") // 配置登陸頁 .loginProcessingUrl("/login") .successForwardUrl("/login/success")// 登陸成功后會(huì)轉(zhuǎn)發(fā)至 /login/success 請求 .permitAll(); // 允許所有人訪問 }) .csrf().disable() .httpBasic();// http請求方式 ,web 瀏覽器會(huì)彈出對話框 } }
再將控制層內(nèi)容替換如下啊,登陸邏輯就是我們請求 /login 會(huì)被轉(zhuǎn)發(fā)至login.html, 然后action 提交至 /login, 這邊已經(jīng)到springSecurity 內(nèi)部, 登陸成功后其會(huì)轉(zhuǎn)發(fā) 至 /login/success;
@GetMapping("/login") public String login() { return "login"; } @PostMapping("/login/success") @ResponseBody public String success() { return "sucess"; }
啟動(dòng)項(xiàng)目,瀏覽器輸入http://localhost:8080/login 或者其它 ip + port + / path 會(huì)自動(dòng)跳轉(zhuǎn)至自定義 登陸頁面
輸入成功后會(huì)跳轉(zhuǎn)的 /login/success ,返回內(nèi)容如下
3.2 自定義登陸流程分析
來自官網(wǎng)的圖片如下,是form表單登陸的流程,
- 首先客戶端會(huì)發(fā)送未授權(quán)請求到服務(wù)端會(huì)被 FilterSecurityInterceptor 攔截標(biāo)明為未授權(quán)的請求,拋出AccessDeniedException;
- ExceptionTranslationFilter 會(huì)捕獲 AccessDeniedException 異常
- 此時(shí) AuthenticationEntryPoint 會(huì)初始化配置流程;
- 捕獲異常后并且重定向到登陸頁面
- 最后 在登陸頁面輸入賬號(hào)密碼就會(huì)進(jìn)入認(rèn)證流程;
3.3 登陸認(rèn)證流程分析
官網(wǎng)登陸時(shí)的認(rèn)證流程圖片如下
- 賬號(hào)密碼輸入成功后,UsernamePasswordAuthenticationFilter 就會(huì)創(chuàng)建UsernamePasswordAuthenticationToken;
- AuthenticationManager儲(chǔ)存著用戶的信息,UsernamePasswordAuthenticationToken 會(huì)被送至這邊進(jìn)行認(rèn)證;
- 如果認(rèn)證失敗,SecurityContextHolder(主要是儲(chǔ)存認(rèn)證的數(shù)據(jù),principle,credentials,authorities)會(huì)被清空, RememberMeServices.loginFail 與 AuthenticationFailureHandler都會(huì)被調(diào)用;
- 如果登陸成功SessionAuthenticationStrategy 會(huì)被喚起重新定制下一次的登陸,認(rèn)證信息會(huì)被儲(chǔ)存至SecurityContextHolder,如果配置了remberMe, RememberMeServices.loginSuccess會(huì)被調(diào)用,ApplicationEventPublisher 會(huì)發(fā)布InteractiveAuthenticationSuccessEvent,AuthenticationSuccessHandler會(huì)被調(diào)用;
簡單概括就是賬號(hào)密碼輸入后進(jìn)入認(rèn)證流程,發(fā)放token, 在manager中認(rèn)證,如果認(rèn)證成功存儲(chǔ)認(rèn)證信息,否則清空認(rèn)證信息;
四 參考文檔
官方文檔
到此這篇關(guān)于詳解springSecurity之java配置篇的文章就介紹到這了,更多相關(guān)springSecurity java配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中SpringSecurity密碼錯(cuò)誤5次鎖定用戶的實(shí)現(xiàn)方法
- Java?JWT實(shí)現(xiàn)跨域身份驗(yàn)證方法詳解
- Java Jwt庫的簡介及使用詳解
- 在Java中使用Jwt的示例代碼
- 基于Java驗(yàn)證jwt token代碼實(shí)例
- Java中使用JWT生成Token進(jìn)行接口鑒權(quán)實(shí)現(xiàn)方法
- Java使用OTP動(dòng)態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證
- JavaWeb使用Session和Cookie實(shí)現(xiàn)登錄認(rèn)證
- Java SpringSecurity+JWT實(shí)現(xiàn)登錄認(rèn)證
相關(guān)文章
一文講透為什么遍歷LinkedList要用增強(qiáng)型for循環(huán)
這篇文章主要為大家介紹了為什么遍歷LinkedList要用增強(qiáng)型for循環(huán)的透徹詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Java實(shí)現(xiàn)SHA-256加密算法的完全解析
SHA-256是一種散列(哈希)算法,用于將任意長度的數(shù)據(jù)映射為固定長度的散列值,以保證數(shù)據(jù)完整性。本文將為大家介紹一下SHA-256加密算法的原理與實(shí)現(xiàn),希望對大家有所幫助2023-02-02java怎樣動(dòng)態(tài)獲取泛型參數(shù)的類型
在Java中,泛型信息在編譯時(shí)會(huì)被擦除,但可以通過特定API獲取運(yùn)行時(shí)的泛型參數(shù)類型,主要API包括Class的getGenericSuperclass()和getGenericInterfaces()方法,以及ParameterizedType的getActualTypeArguments()方法2024-09-09SpringBoot 項(xiàng)目使用hutool 工具進(jìn)行 http 接口調(diào)用的處理方
在實(shí)際的開發(fā)過程中一個(gè)互聯(lián)網(wǎng)的項(xiàng)目來說 ,有可能會(huì)涉及到調(diào)用外部接口的實(shí)際業(yè)務(wù)場景,下面通過本文給大家介紹SpringBoot 項(xiàng)目 使用hutool 工具進(jìn)行 http 接口調(diào)用的處理方法,需要的朋友可以參考下2022-06-06SpringMvc MultipartFile實(shí)現(xiàn)圖片文件上傳示例
本篇文章主要介紹了SpringMvc MultipartFile實(shí)現(xiàn)圖片文件上傳示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02Spring Cloud Netflix架構(gòu)淺析(小結(jié))
這篇文章主要介紹了Spring Cloud Netflix架構(gòu)淺析(小結(jié)),詳解的介紹了Spring Cloud Netflix的概念和組件等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01