apache shiro 如何升级_Shiro登录认证
????我們使用一個springboot+Shiro集成項目來了解一下Shiro在登錄認證方面是如何運作的。
1、pom依賴添加
<dependency> <groupId>org.apache.shirogroupId> <artifactId>shiro-coreartifactId> <version>1.2.2version> dependency> <dependency> <groupId>org.apache.shirogroupId> <artifactId>shiro-springartifactId> <version>1.2.2version> dependency> <dependency> <groupId>org.apache.shirogroupId> <artifactId>shiro-ehcacheartifactId> <version>1.2.2version> dependency>2.數據庫用戶權限表、實體類、用戶權限DAO操作,略略略。
3.攔截器會在下一篇專門說明攔截器配置使用,略。
4.realm配置
????????在Shiro中,最終是通過Realm來獲取應用程序中的用戶、角色及權限信息的。
public class MyShiroRealm extends AuthorizingRealm通過繼承公共Realm抽象類,實現認證處理邏輯抽象方法
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("doGetAuthenticationInfo:" + token); // 將AuthenticationToken強轉為AuthenticationToken對象 UsernamePasswordToken upToken = (UsernamePasswordToken) token; // 獲得從表單傳過來的用戶名 String username = upToken.getUsername(); // 從數據庫查看是否存在用戶 UserService userService = new UserService(); // 如果用戶不存在,拋此異常 if (!userService.selectUsername(username)) { throw new UnknownAccountException("無此用戶名!"); } // 認證的實體信息,可以是username,也可以是用戶的實體類對象,這里用的用戶名 Object principal = username; // 從數據庫中查詢的密碼 Object credentials = userService.selectPassword(username); // 顏值加密的顏,可以用用戶名 ByteSource credentialsSalt = ByteSource.Util.bytes(username); // 當前realm對象的名稱,調用分類的getName() String realmName = this.getName(); // 創建SimpleAuthenticationInfo對象,并且把username和password等信息封裝到里面 // 用戶密碼的比對是Shiro幫我們完成的 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName); return info; }然后在Config配置類中將自定義的realm加載到容器中:
@Configurationpublic class ShiroConfigBean { @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; }}容器啟動時候會把這個Bean掃描進去,后邊進行登錄驗證進行密碼驗證就會調用這個Bean,怎么調用的呢?往下看。
5.登錄代碼
@RequestMapping("/login.action") public String login(String username, String password, Map map, HttpSession session) { System.out.println(username + "---" + password); // 獲得當前Subject Subject currentUser = SecurityUtils.getSubject(); // 驗證用戶是否驗證,即是否登錄 if (!currentUser.isAuthenticated()) { String msg = ""; // 把用戶名和密碼封裝為 UsernamePasswordToken 對象 UsernamePasswordToken token = new UsernamePasswordToken(username, password); // remembermMe記住密碼 token.setRememberMe(true); try { // 執行登錄. currentUser.login(token); // 登錄成功... return "redirect:/LoginSuccess.action"; } catch (IncorrectCredentialsException e) { msg = "登錄密碼錯誤"; System.out.println("登錄密碼錯誤!!!" + e); } catch (ExcessiveAttemptsException e) { msg = "登錄失敗次數過多"; System.out.println("登錄失敗次數過多!!!" + e); } catch (LockedAccountException e) { msg = "帳號已被鎖定"; System.out.println("帳號已被鎖定!!!" + e); } catch (DisabledAccountException e) { msg = "帳號已被禁用"; System.out.println("帳號已被禁用!!!" + e); } catch (ExpiredCredentialsException e) { msg = "帳號已過期"; System.out.println("帳號已過期!!!" + e); } catch (UnknownAccountException e) { msg = "帳號不存在"; System.out.println("帳號不存在!!!" + e); } catch (UnauthorizedException e) { msg = "您沒有得到相應的授權!"; System.out.println("您沒有得到相應的授權!" + e); } catch (Exception e) { System.out.println("出錯!!!" + e); } map.put("msg", msg); return "/index"; } // 登錄成功,重定向到LoginSuccess.action return "redirect:/LoginSuccess.action"; }上邊一大堆代碼,咱們只看三句就可以:
// 獲得當前Subject(shiro核心類庫中的方法)Subject currentUser = SecurityUtils.getSubject(); // 把用戶名和密碼封裝為 UsernamePasswordToken 對象UsernamePasswordToken token = new UsernamePasswordToken(username, password);//?執行登錄.currentUser.login(token);上面三個方法都是Shiro類庫中的方法,直接調用。
????用戶從登錄頁將表單中用戶名和密碼傳遞過來后,封裝成UsernamePasswordToken 對象傳入到Shiro的登錄入口方法login中,看一下login方法:
進入securityManager安全管理器里邊的login方法:
然后一直往下走,找到獲取Realms的方法:
進入doSingleRealmAuthentication方法:
從shiro緩存中讀取用戶信息,如果沒有,才從realm中獲取信息。點擊這個doGetAuthenticationInfo方法,就到了我們第4步中進行realm配置時實現的抽象方法:
再進入這個實現方法時會出現我們配置的realm:
以上步驟是通過我們自定義的realm根據表單信息查詢數據庫獲取到數據庫用戶信息和表單信息的一個SimpleAuthenticationInfo 對象:
@param principal the 'primary' principal associated with the specified realm.@param?hashedCredentials?the?hashed?credentials?that?verify?the?given?principal.@param credentialsSalt the salt used when hashing the given hashedCredentials@param realmName the realm from where the principal and credentials were acquired.SimpleAuthenticationInfo?info?=?new?SimpleAuthenticationInfo(??principal,?//認證的實體信息,可以是實體類也可以是用戶名??hashedCredentials?,?//用于跟表單密碼進行比對的已存儲的密碼值??credentialsSalt,?//已存儲密碼加密算法中使用的鹽值??realmName?//realm的名稱);然后才開始進行密碼驗證。
6、密碼驗證
獲取到SimpleAuthenticationInfo?對象,開始使用算法進行比較。
assertCredentialsMatch(token, info);token中保存了表單信息,info中保存了數據庫中密碼信息。
????????首先需要獲取指定的憑證匹配器,就是使用哪種算法(常見的散列算法如MD5、SHA等,加密算法會在加密章進行講解)來進行驗證,把表單中的密碼通過加鹽算法進行計算,得出的值與數據庫中的值進行比較,相同就驗證通過。
可以在realm配置時進行指定:
@Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:這里使用MD5算法; hashedCredentialsMatcher.setHashIterations(1024);// 散列的次數,比如散列兩次,相當于md5(md5("")); return hashedCredentialsMatcher; } @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; }看完之后,明白了嗎?沒有的話再看一遍!
總結
以上是生活随笔為你收集整理的apache shiro 如何升级_Shiro登录认证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python按字节读取文件_Python
- 下一篇: python微信聊天机器人_python