SpringSecurity+Redis認證過程是怎樣的
前言引入
當今市面上用於權限管理的流行的技術堆疊組合是
ssm shrio
SpringCloud SpringBoot SpringSecurity
這種搭配自然有其搭配的特點,由於SpringBoot的自動注入配置原理,在創建專案時就自動注入管理SpringSecurity的過濾器容器(DelegatingFilterProxy),而這個過濾器是整個SpringSercurity的核心。掌握著SpringSercurity整個權限認證過程,而SpringBoot很香的幫你將其自動注入了,而用ssm
去整合Security,將會耗用大量的配置文件,不易於開發,而Security的微服務權限方案,更是能和Cloud完美融合,於是Security比Shrio更強大,功能更齊全。
Security的核心設定檔
核心:Class SecurityConfig extends WebSecurityConfigurerAdapter
##繼承了WebSecurityConfigurerAdapter後我們專注於configure方法對於在整個安全認證的過程進行相關的配置,當然在配置之前我們先簡單了解一下流程簡單的看了整個權限認證的流程,很輕易的總結得出,SpringSecurity核心的就是以下幾種配置項目了- 攔截器(Interceptor)
- #過濾器(Filter)
- 處理器(Handler,異常處理器,登入成功處理器)
那我們就先透過設定來完成認證過程吧! ! ! !
Security的認證流程假設我們要實作一下的認證功能1. 是登入請求- 我們需要先判斷驗證碼是否正確(驗證碼過濾器,透過addFilerbefore實現前置攔截)
- #再判斷用戶名密碼是否正確(使用自帶的用戶名密碼過濾器,
UsernamePasswordAuthenticationFilter)
- 設定異常處理器(Handler)透過IO流將例外訊息寫出
UsernamePasswordAuthenticationFilter的密碼校驗規則是基於AuthenticationManagerBuilder(認證管理器)下的UserDetailsService裡的規則進行驗證的:
其中的核心方法:
UserDetails *loadUserByUsername(String username)透過請求參數的使用者名稱去資料庫查詢是否存在,存在則將其封裝在UserDetails裡面,而驗證過程是透過AuthenticationManagerBuilder取得到UserDetail裡的username和password來校驗的,
這樣我們就可以透過
- 設定yaml檔案設定帳號密碼
- 透過資料庫結合UserDetail來設定帳號密碼
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { SysUser sysUser = sysUserService.getByUsername(username); if (sysUser == null) { throw new UsernameNotFoundException("用户名或密码不正确"); } // 注意匹配参数,前者是明文后者是暗纹 System.out.println("是否正确"+bCryptPasswordEncoder.matches("111111",sysUser.getPassword())); return new AccountUser(sysUser.getId(), sysUser.getUsername(), sysUser.getPassword(), getUserAuthority(sysUser.getId())); }
核心設定檔:
package com.markerhub.config; import com.markerhub.security.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired LoginFailureHandler loginFailureHandler; @Autowired LoginSuccessHandler loginSuccessHandler; @Autowired CaptchaFilter captchaFilter; @Autowired JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Autowired JwtAccessDeniedHandler jwtAccessDeniedHandler; @Autowired UserDetailServiceImpl userDetailService; @Autowired JwtLogoutSuccessHandler jwtLogoutSuccessHandler; @Bean JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager()); return jwtAuthenticationFilter; } @Bean BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } private static final String[] URL_WHITELIST = { "/login", "/logout", "/captcha", "/favicon.ico", }; protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() // 登录配置 .formLogin() .successHandler(loginSuccessHandler) .failureHandler(loginFailureHandler) .and() .logout() .logoutSuccessHandler(jwtLogoutSuccessHandler) // 禁用session .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 配置拦截规则 .and() .authorizeRequests() .antMatchers(URL_WHITELIST).permitAll() .anyRequest().authenticated() // 异常处理器 .and() .exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler) // 配置自定义的过滤器 .and() .addFilter(jwtAuthenticationFilter()) .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class) ; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailService); } }
- 透過JFilter來查看是否為登入狀態
- ##在登入請求前新增篩選器
- 注意驗證碼儲存在redis的失效時間,如果超過失效時間將會被驗證碼攔截器攔截下來
- 需要準備一個產生驗證碼的接口,儲存在Redis中
- 使用完驗證碼需要將其刪除
// 校验验证码逻辑 private void validate(HttpServletRequest httpServletRequest) { String code = httpServletRequest.getParameter("code"); String key = httpServletRequest.getParameter("token"); if (StringUtils.isBlank(code) || StringUtils.isBlank(key)) { System.out.println("验证码校验失败2"); throw new CaptchaException("验证码错误"); } System.out.println("验证码:"+redisUtil.hget(Const.CAPTCHA_KEY, key)); if (!code.equals(redisUtil.hget(Const.CAPTCHA_KEY, key))) { System.out.println("验证码校验失败3"); throw new CaptchaException("验证码错误"); } // 一次性使用 redisUtil.hdel(Const.CAPTCHA_KEY, key); }
登入後複製以上是SpringSecurity+Redis認證過程是怎樣的的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

要查看 Redis 中的所有鍵,共有三種方法:使用 KEYS 命令返回所有匹配指定模式的鍵;使用 SCAN 命令迭代鍵並返回一組鍵;使用 INFO 命令獲取鍵的總數。

Redis 使用哈希表存儲數據,支持字符串、列表、哈希表、集合和有序集合等數據結構。 Redis 通過快照 (RDB) 和追加只寫 (AOF) 機制持久化數據。 Redis 使用主從復制來提高數據可用性。 Redis 使用單線程事件循環處理連接和命令,保證數據原子性和一致性。 Redis 為鍵設置過期時間,並使用 lazy 刪除機制刪除過期鍵。

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

理解 Redis 源碼的最佳方法是逐步進行:熟悉 Redis 基礎知識。選擇一個特定的模塊或功能作為起點。從模塊或功能的入口點開始,逐行查看代碼。通過函數調用鏈查看代碼。熟悉 Redis 使用的底層數據結構。識別 Redis 使用的算法。

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。
