您好,登錄后才能下訂單哦!
本篇內容主要講解“SpringSecurity+Redis認證過程是怎樣的”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringSecurity+Redis認證過程是怎樣的”吧!
當今市面上用于權限管理的流行的技術棧組合是
ssm+shrio
SpringCloud+SpringBoot+SpringSecurity
這種搭配自然有其搭配的特點,由于SpringBoot的自動注入配置原理,在創建項目時就自動注入管理SpringSecurity的過濾器容器(DelegatingFilterProxy),而這個過濾器是整個SpringSercurity的核心。掌握著SpringSercurity整個權限認證過程,而SpringBoot很香的幫你將其自動注入了,而用ssm
去整合Security,將會耗用大量的配置文件,不易于開發,而Security的微服務權限方案,更是能和Cloud完美融合,于是Security比Shrio更強大,功能更齊全。
核心:Class SecurityConfig extends WebSecurityConfigurerAdapter
繼承了WebSecurityConfigurerAdapter后我們關注于configure方法對于在整個安全認證的過程進行相關的配置,當然在配置之前我們先簡單了解一下流程
簡單的看了整個權限認證的流程,很輕易的總結得出,SpringSecurity核心的就是以下幾種配置項了
攔截器(Interceptor)
過濾器(Filter)
處理器(Handler,異常處理器,登錄成功處理器)
那我們就首先通過配置來完成認證過程吧!!!!
假設我們要實現一下的認證功能
我們需要先判斷驗證碼是否正確(驗證碼過濾器,通過addFilerbefore實現前置攔截)
再判斷用戶名密碼是否正確(使用自帶的用戶名密碼過濾器,UsernamePasswordAuthenticationFilter)
配置異常處理器(Handler)通過IO流將異常信息寫出
關于密碼校驗的流程:
UsernamePasswordAuthenticationFilter的密碼校驗規則是基于AuthenticationManagerBuilder(認證管理器)下的 UserDetailsService里的規則進行驗證的:
其中的核心方法:
1.public UserDetails *loadUserByUsername(String username)
通過請求參數的用戶名去數據庫查詢是否存在,存在則將其封裝在UserDetails里面,而驗證過程是通過AuthenticationManagerBuilder獲取到UserDetail里的username和password來校驗的,
這樣我們就可以通過
配置yaml文件設置賬號密碼
通過數據庫結合UserDetail來設置賬號密碼
(UserDetailsService中的方法,注意需要將UserDetailsService注入AuthenticationManagerBuilder中)
@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); } }
通過JwtfFilter來查看是否為登錄狀態
本質上還是編寫過濾器鏈:
在登錄請求前添加過濾器
注意驗證碼存儲在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認證過程是怎樣的”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。