日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot 整合 Shiro 密碼登錄與郵件驗證碼登錄功能(多 Realm 認證)

瀏覽:30日期:2023-03-23 17:29:45

導入依賴(pom.xml)

<!--整合Shiro安全框架--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--集成jwt實現token認證--> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.2.0</version> </dependency>

在 SpringBoot 項目配置 config 包下創建 ShiroConfig 配置類

@Configurationpublic class ShiroConfig { /** * ShiroFilterFactoryBean * <p> * anon:無需認證就可以訪問 * authc:必須認證才能訪問 * user:必須擁有 記住我 功能才能用 * perms:擁有對某個資源的權限能訪問 * role:擁有某個角色權限能訪問 */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier('securityManager') DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 設置安全管理器 factoryBean.setSecurityManager(defaultWebSecurityManager); // 添加shiro的內置過濾器 Map<String, String> filterMap = new LinkedHashMap<>(); // 放行不需要權限認證的接口 // 網站首頁 filterMap.put('/', 'anon'); filterMap.put('/index', 'anon'); filterMap.put('/index.html', 'anon'); // 不驗證跳轉接口 filterMap.put('/into/**', 'anon'); // 需要權限認證的接口 // 驗證跳轉接口 filterMap.put('/verifyInto/**', 'authc'); factoryBean.setFilterChainDefinitionMap(filterMap); // 訪問沒有授權的資源 factoryBean.setLoginUrl('redirect:/into/login'); // 設置無權限時跳轉的url factoryBean.setUnauthorizedUrl('redirect:/into/login'); return factoryBean; } /** * 管理shiro的生命周期 */ @Bean('lifecycleBeanPostProcessor') public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 注入 密碼登錄CustomRealm */ @Bean @DependsOn('lifecycleBeanPostProcessor') public UserPasswordRealm userPasswordRealm() { return new UserPasswordRealm(); } /** * 注入 郵箱驗證登錄EmailRealm */ @Bean @DependsOn('lifecycleBeanPostProcessor') public UserEmailRealm userEmailRealm() { return new UserEmailRealm(); } /** * 默認安全管理器 */ @Bean public DefaultWebSecurityManager securityManager(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm, AbstractAuthenticator abstractAuthenticator) { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); List<Realm> realms = new ArrayList<>(); realms.add(userPasswordRealm); realms.add(userEmailRealm); defaultWebSecurityManager.setRealms(realms); // 記住我 defaultWebSecurityManager.setRememberMeManager(cookieRememberMeManager()); defaultWebSecurityManager.setAuthenticator(abstractAuthenticator); return defaultWebSecurityManager; } /** * 認證器 把我們的自定義驗證加入到認證器中 */ @Bean public AbstractAuthenticator abstractAuthenticator(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm) { // 自定義模塊化認證器,用于解決多realm拋出異常問題 //開始沒用自定義異常問題,發現不管是賬號密碼錯誤還是什么錯誤 //shiro只會拋出一個AuthenticationException異常 ModularRealmAuthenticator authenticator = new MyCustomModularRealmAuthenticator(); // 認證策略:AtLeastOneSuccessfulStrategy(默認),AllSuccessfulStrategy,FirstSuccessfulStrategy authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); // 加入realms List<Realm> realms = new ArrayList<>(); realms.add(userPasswordRealm); realms.add(userEmailRealm); authenticator.setRealms(realms); return authenticator; } /** * 加入shiro注解 代理生成器 切面 */ @Bean @DependsOn({'lifecycleBeanPostProcessor'}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } /** * 加入shiro注解 切點 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * 設置cookie 記住我生成cookie */ @Bean public CookieRememberMeManager cookieRememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); return cookieRememberMeManager; } /** * 設置cookie有效時間 */ @Bean public SimpleCookie rememberMeCookie() { /*這個參數是cookie的名稱,對應前端頁面的checkbox的name=remremberMe*/ SimpleCookie simpleCookie = new SimpleCookie('rememberMe'); /*cookie的有效時間為30天,單位秒*/ simpleCookie.setMaxAge(259200); return simpleCookie; }}

創建自定義驗證器 MyCustomModularRealmAuthenticator 類

public class MyCustomModularRealmAuthenticator extends ModularRealmAuthenticator { @Override protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) { AuthenticationStrategy authenticationStrategy = this.getAuthenticationStrategy(); AuthenticationInfo authenticationInfo = authenticationStrategy.beforeAllAttempts(realms, token); Iterator var5 = realms.iterator(); while (var5.hasNext()) { Realm realm = (Realm) var5.next(); authenticationInfo = authenticationStrategy.beforeAttempt(realm, token, authenticationInfo); if (realm.supports(token)) { AuthenticationInfo info = null; Throwable t = null; info = realm.getAuthenticationInfo(token); authenticationInfo = authenticationStrategy.afterAttempt(realm, token, info, authenticationInfo, t); } } authenticationInfo = authenticationStrategy.afterAllAttempts(token, authenticationInfo); return authenticationInfo; }}

創建密碼登錄時驗證授權 UserPasswordRealm 類

@Componentpublic class UserPasswordRealm extends AuthorizingRealm { // 注入用戶業務 @Autowired private UserMapper userMapper; /** * 授權 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println('————密碼授權————doGetAuthorizationInfo————'); return null; } /** * 認證 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println('————密碼認證————doGetAuthenticationInfo————'); UsernamePasswordToken userToken = (UsernamePasswordToken) token; // 連接數據庫 查詢用戶數據 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq('user_name', userToken.getUsername()); User user = userMapper.selectOne(wrapper); // 驗證用戶 if (user == null) { throw new UnknownAccountException(); } return new SimpleAuthenticationInfo('', user.getUserPassword(), ''); } /** * 用來判斷是否使用當前的 realm * * @param var1 傳入的token * @return true就使用,false就不使用 */ @Override public boolean supports(AuthenticationToken var1) { return var1 instanceof UsernamePasswordToken; }}

創建郵件驗證碼登錄時驗證授權UserEmailRealm 類

@Componentpublic class UserEmailRealm extends AuthorizingRealm { // 注入用戶業務 @Autowired UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println('————郵箱登錄授權————doGetAuthorizationInfo————'); return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println('————郵箱登錄認證————doGetAuthenticationInfo————'); UserEmailToken userEmailToken = (UserEmailToken) token; String userEmail = (String) userEmailToken.getPrincipal(); // 連接數據庫 查詢用戶數據 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq('user_email', userEmail); User user = userService.getOne(wrapper); //因為沒有密碼,并且驗證碼在之前就驗證了 if (user == null) { throw new UnknownAccountException(); } return new SimpleAuthenticationInfo('', userEmail, ''); } /** * 用來判斷是否使用當前的 realm * * @param var1 傳入的token * @return true就使用,false就不使用 */ @Override public boolean supports(AuthenticationToken var1) { return var1 instanceof UserEmailToken; }}

創建郵件驗證碼登錄驗證通過生成令牌的 UserEmailToken 類(密碼登錄時使用shiro默認的 UsernamePasswordToken 令牌)

@Data // 使用lombok 生成get方法、set方法public class UserEmailToken implements HostAuthenticationToken, RememberMeAuthenticationToken { private String userEmail; private boolean rememberMe; private String host; public UserEmailToken() { this.rememberMe = false; } public UserEmailToken(String userEmail) { this(userEmail, false, null); } public UserEmailToken(String userEmail, boolean rememberMe) { this(userEmail, rememberMe, null); } public UserEmailToken(String userEmail, boolean rememberMe, String host) { this.userEmail = userEmail; this.rememberMe = rememberMe; this.host = host; } @Override public String getHost() { return host; } @Override public boolean isRememberMe() { return rememberMe; } /** * 重寫getPrincipal方法 */ @Override public Object getPrincipal() { return userEmail; } /** * 重寫getCredentials方法 */ @Override public Object getCredentials() { return userEmail; }}

創建密碼鹽值加密 MDPasswordUtil 工具類

public class MDPasswordUtil { public String getMDPasswordUtil(String userName, String userPassword) { String hashAlgorithmName = 'MD5'; // 加密方式:md5加密 Object credentials = userPassword; // 密碼 Object salt = ByteSource.Util.bytes(userName); // 鹽 int hashIterations = 512; // 加密次數 Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); return result.toString(); }}

控制層用戶密碼登錄

// 用戶密碼登錄 @PostMapping('/passwordLogin') public String userLogin(@RequestParam('userName') String userName, @RequestParam('userPassword') String userPassword, HttpSession session, Model model) { // 獲取當前的用戶 Subject subject = SecurityUtils.getSubject(); // 對密碼進行MD5鹽值加密 String md5Password = new MDPasswordUtil().getMDPasswordUtil(userName, userPassword); // 封裝用戶的登錄數據 UsernamePasswordToken token = new UsernamePasswordToken(userName, md5Password); //rememberme記住我 token.setRememberMe(true); try { // 登錄,驗證,保存令牌 subject.login(token); //查詢登錄信息 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq('user_name', userName); User user = userService.getOne(wrapper); //保存登錄用戶信息 session.setAttribute(user.getUserId().toString(), user); return 'admin'; } catch (UnknownAccountException e) { model.addAttribute('userError', '用戶名錯誤!請重新輸入。'); return 'login'; } catch (IncorrectCredentialsException ice) { model.addAttribute('pwError', '密碼錯誤!請重新輸入。'); return 'login'; } }

控制層用戶郵件驗證碼密碼登錄

// 用戶郵箱登錄 @PostMapping('/emailLogin') public String emailLogin(@RequestParam('userEmail') String userEmail,@RequestParam('emailCode') String emailCode,HttpSession session, Model model) { // 根據userEmail從session中取出發送的驗證碼 String sendEmailCode = (String) session.getAttribute(userEmail); // 比對驗證碼 if (StringUtils.isNoneBlank(sendEmailCode) && sendEmailCode.equals(emailCode)) { try { UserEmailToken token = new UserEmailToken(userEmail); //rememberme記住我 token.setRememberMe(true); // 登錄,驗證,保存令牌 Subject subject = SecurityUtils.getSubject(); subject.login(token); //查詢登錄信息 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq('user_email', userEmail); User user = userService.getOne(wrapper); //保存登錄用戶信息 session.setAttribute(user.getUserId().toString(), user); // 銷毀驗證碼 session.removeAttribute(emailCode); return 'admin'; } catch (Exception e) { model.addAttribute('error', '驗證碼錯誤!請重新輸入。'); return 'login'; } } else { return 'login'; } }

SpringBoot 整合 Shiro 密碼登錄與郵件驗證碼登錄(多 Realm 認證)就可以了 (有點多,哈哈哈)

推薦大神:狂神說Java

到此這篇關于SpringBoot 整合 Shiro 密碼登錄與郵件驗證碼登錄(多 Realm 認證)的文章就介紹到這了,更多相關SpringBoot 整合 Shiro登錄內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
激情综合亚洲| 欧美一区久久久| 日韩综合一区| 午夜在线视频观看日韩17c| 国产精品久久久久久模特| 99久久夜色精品国产亚洲1000部| 最新亚洲国产| 久久久久国产精品一区三寸| 日韩欧美激情电影| 久久久久国产精品一区三寸| 91福利精品在线观看| 四虎884aa成人精品最新| 亚洲午夜国产成人| 欧产日产国产精品视频| 日本麻豆一区二区三区视频| 人人精品亚洲| 麻豆精品在线视频| 亚洲啊v在线免费视频| 91精品国产乱码久久久久久久| 欧美视频一区| 丝袜亚洲精品中文字幕一区| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 99精品视频在线观看免费播放| 日韩va亚洲va欧美va久久| 鲁鲁在线中文| 久久精品99国产精品日本| 亚洲美洲欧洲综合国产一区| 国产在线一区不卡| 久久国内精品自在自线400部| 先锋影音国产一区| 精品丝袜在线| 国产suv精品一区| 69精品国产久热在线观看| 国产视频久久| 久久久成人网| 国产成人精品三级高清久久91| 欧美日韩精品一区二区三区在线观看| 国产亚洲精品久久久久婷婷瑜伽| 91欧美国产| 国产欧美在线| 偷拍亚洲精品| 亚洲一区二区三区无吗| 黑丝一区二区三区| 久久在线电影| 日韩欧美一区二区三区免费看| 久久不卡日韩美女| 国产欧美一区二区三区国产幕精品| 蜜桃久久久久久| 亚洲精品123区| 麻豆视频一区| 蜜臀久久99精品久久久久久9| 天堂中文av在线资源库| 国产精品va| 日韩精品成人在线观看| 日本国产精品| 激情综合五月| 国产日韩欧美一区在线| 99日韩精品| 99精品美女| 日韩成人免费| 久久精品二区亚洲w码| 日韩精彩视频在线观看| 精品1区2区3区4区| 久久免费国产| 97视频热人人精品免费| 高清久久一区| 国产精品亚洲综合色区韩国 | 国产精品欧美日韩一区| 日韩av资源网| 国产精品一区二区三区www| 国产欧美日韩精品一区二区免费 | 爽好久久久欧美精品| 欧美在线综合| 免费在线观看一区二区三区| 久久香蕉国产| 日韩电影免费网址| 国产激情一区| 国产精品三p一区二区| 日韩va亚洲va欧美va久久| 亚洲一区亚洲| 亚洲一区日本| 国产亚洲激情| 日韩视频一区| 激情丁香综合| 九九久久婷婷| 国模精品一区| 日本a口亚洲| 久久女人天堂| 亚洲天堂一区二区| 国产精品嫩草99av在线| 在线观看视频免费一区二区三区| 日韩av在线播放中文字幕| 国产精品一区亚洲| www.九色在线| 亚洲电影在线| 9久re热视频在线精品| 亚洲一区欧美| 久久99蜜桃| 99热精品久久| 亚洲精品动态| 久久一区精品| 国产一区观看| 天海翼精品一区二区三区| 国产精品一区二区免费福利视频 | 免费在线亚洲欧美| 丁香六月综合| 亚洲精品a级片| 亚洲精品大片| 美女久久久精品| 99精品视频精品精品视频| 午夜一级久久| 国产极品久久久久久久久波多结野| 日韩欧美自拍| 伊人精品久久| 精品视频在线你懂得| 激情五月色综合国产精品| 日本不卡一二三区黄网| 精品国产鲁一鲁****| 国产二区精品| 国产日产一区| 国产精品99免费看| 亚洲资源网站| 高清精品久久| 亚洲日本国产| 日韩电影免费网址| 午夜久久av| 精品成人免费一区二区在线播放| 亚洲精品在线国产| 日韩一区二区在线免费| 中文字幕一区二区三区在线视频| 麻豆精品在线视频| 在线亚洲精品| 精品中文字幕一区二区三区四区| 激情婷婷久久| 国产精品99久久免费| 好吊视频一区二区三区四区| 欧美日韩一区二区三区四区在线观看 | 精品精品国产三级a∨在线| 婷婷久久一区| 久久最新视频| 欧美日韩少妇| 日欧美一区二区| 日本一二区不卡| 国产亚洲精品v| 嫩呦国产一区二区三区av| 亚洲无线一线二线三线区别av| 中文字幕一区二区av| 国产激情欧美| 精品一区免费| 国产欧美一级| 亚洲欧美一区在线| 国产精品久久久久久av公交车| 欧美成a人免费观看久久| 亚洲毛片在线免费| 福利精品在线| 亚洲主播在线| 国产一区二区三区四区| 久久99伊人| 国产中文欧美日韩在线| 亚洲在线免费| 久久亚州av| 国产农村妇女精品一区二区| 免费日韩一区二区三区| 色婷婷久久久| 91精品国产自产精品男人的天堂| 视频福利一区| 欧美精品影院| 国产精品88久久久久久| 国产精品第一| 国产精品嫩草99av在线| 精品美女视频| 一区二区国产在线观看| 福利一区在线| 日韩激情一区二区| 在线日韩欧美| 国产精品99久久免费| 午夜宅男久久久| 亚洲啊v在线| 欧美一区精品| 国产精品美女久久久| 日本一二区不卡| 欧美一区二区三区久久精品| 国产伊人精品| 国际精品欧美精品| 亚洲精品激情| 尹人成人综合网| 日本а中文在线天堂| 日韩va欧美va亚洲va久久| 亚洲大全视频| av中文资源在线资源免费观看| 91麻豆精品| 美女尤物久久精品| 久久久久一区| 麻豆国产精品一区二区三区| 亚洲伊人精品酒店| 国产高清一区| 亚洲www啪成人一区二区| 欧美精品99| 日本在线成人| 日韩精品一级二级|