shiro系列3:MD5鹽值加密認證流程


簡介:

  對於同一密碼,同一加密算法會產生相同的hash值,這樣,當用戶進行身份驗證時,也可對用戶輸入的明文密碼應用相同的hash加密算法,得出一個hash值,然后使用該hash值和之前存儲好的密文值進行對照,如果兩個值相同,則密碼認證成功,否則密碼認證失敗。
  但是這樣存在很大的問題,不同的用戶極有可能會使用相同的密碼,那么這些用戶對應的密文也會相同,這樣,當存儲用戶密碼的數據庫泄露后,攻擊者會很容易便能找到相同密碼的用戶,從而也降低了破解密碼的難度,因此,在對用戶密碼進行加密時,需要考慮對密碼進行掩飾,即使是相同的密碼,也應該要保存為不同的密文,即使用戶輸入的是弱密碼,也需要考慮進行增強,從而增加密碼被攻破的難度,而使用帶鹽的加密hash值便能滿足該需求。
  所以為了達到即便是相同的密碼在加密之后,密文也不一樣的需求。我們需要對密碼進行鹽值加密。

 

使用:

1、 獲取當前的 Subject,調用 SecurityUtils.getSubject()。

2、測試當前的用戶是否已經被認證,即是否已經登錄,調用 Subject 的 isAuthenticated() 

3、若沒有被認證,對密碼進行md5鹽值加密,首先數據庫中的密碼必須是同一種加密方式

4、把用戶名和密文密碼封裝為 UsernamePasswordToken 對象。

5、 執行登錄:調用 Subject 的 login(AuthenticationToken) 方法。

@RequestMapping("/login")
public String login(@RequestParam("username") String username, 
                    @RequestParam("password") String password){    
    Subject currentUser = SecurityUtils.getSubject();
    if (!currentUser.isAuthenticated()) {
     // 對密碼進行MD5鹽值加密
     String enPassword = getEnPassword(username,password);
       //把用戶名和密文密碼封裝為UsernamePasswordToken對象,這個token會被傳到Realm中比對
         UsernamePasswordToken token = 
         new UsernamePasswordToken(username, enPassword);
        //rememberme記住我
        token.setRememberMe(true);
        try {
           //執行登錄. 
           currentUser.login(token);
           } catch (AuthenticationException ae) { // 所有認證時異常的父類.
               System.out.println("登錄失敗: " + ae.getMessage());
           }
       }
    return "redirect:/list.jsp";
}

// 對密碼進行md5鹽值加密,鹽值可以是用戶名,鹽值必須是唯一的
public String getEnPassword(String username,String password){
    String hashAlgorithmName = "MD5";  // 加密方式:md5加密
    Object credentials = password;   // 密碼
    Object salt = ByteSource.Util.bytes(username);  //
    int hashIterations = 1024;  // 加密次數
    Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
    return result.toString();
}

 

 

6、自定義 Realm 的方法,從數據庫中獲取對應的記錄, 返回給 Shiro。

(1)、 實際上需要繼承 org.apache.shiro.realm.AuthenticatingRealm 類。

(2)、 實現 doGetAuthenticationInfo(AuthenticationToken) 方法。

(3)、通過 AuthenticatingRealm 的 credentialsMatcher 屬性來進行的密碼的比對

public class ShiroRealm extends AuthenticatingRealm{
   // 認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        //1. 把 AuthenticationToken 轉換為 UsernamePasswordToken
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
//2. 從 UsernamePasswordToken 中來獲取 username String username = upToken.getUsername();
//3. 調用數據庫的方法, 從數據庫中查詢 username 對應的用戶記錄 User user = getUser(String username);
//4. 若用戶不存在, 則可以拋出 UnknownAccountException 異常 if(user.isEmpty()){ throw new UnknownAccountException("用戶不存在!"); }
//5. 根據用戶信息的情況, 決定是否需要拋出其他的 AuthenticationException 異常. if("monster".equals(username)){ throw new LockedAccountException("用戶被鎖定"); }
//6. 根據用戶的情況, 來構建 AuthenticationInfo 對象並返回. //以下信息是從數據庫中獲取的.AuthenticationInfo封裝着從數據庫中查詢出來的帳號密碼 //1). principal: 認證的實體信息. 可以是 username, 也可以是數據表對應的用戶的實體類對象. Object principal = user.getUserName();
//2). credentials: 密碼. Object credentials = user.getPassword;
//3). realmName: 當前 realm 對象的 name. 調用父類的 getName() 方法即可 String realmName = getName();
SimpleAuthenticationInfo info
= new SimpleAuthenticationInfo(principal, credentials, realmName); return info; } }

 

 

6、需要用到的pom

復制代碼
        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.crazycake</groupId>
            <artifactId>shiro-redis</artifactId>
            <version>3.2.3</version>
            <!-- 排除最新3.1.0版本,引用2.9.0版本,https://github.com/alexxiyang/shiro-redis/issues/113 -->
            <exclusions>
                <exclusion>
                    <groupId>redis.clients</groupId>
                    <artifactId>jedis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>    
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM