shiro密碼的比對,密碼的MD5加密,MD5鹽值加密,多個Relme


有具體問題的可以參考之前的關於shiro的博文,關於shiro的博文均是一次工程的內容

 

 

密碼的比對
 
通過AuthenticatingRealm的CredentialsMatcher方法
密碼的加密,主要是在CredentialsMatcher的....

 

 

 

 

密碼的MD5加密
數據表中保存的密碼,不應該是明文的,而且不能反推得到密碼
 
1.如何把一個字符串加密成MD5

 使用其提供的接口實現

 

2.替換當前的Realm的CredentialsMatcher屬性,直接使用HashedCredentialsMatcher對象,
並且設置加密算法
applicatonContext.xml文件中

 

    <!--
            3.配置Realm
            3.1直接實現Realm接口的bean
          -->
    <bean id="jdbcRealm"  class="com.MrChengs.shiro.realms.ShiroRealm">
        <property name="credentialsMatcher">
            <bean  class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                 
                 <!-- 加密的方法 -->
                 <property name="hashAlgorithmName"  value="MD5"></property>
                 
                 <!-- 指定加密的次數 -->
                 <property name="hashIterations"  value="20"></property>
            </bean>
        </property>
        
    </bean>

 

 

看源碼:

public SimpleHash(String algorithmName, Object source, Object  salt, int hashIterations)
            throws CodecException, UnknownAlgorithmException {
        if (!StringUtils.hasText(algorithmName)) {
            throw new NullPointerException("algorithmName  argument cannot be null or empty.");
        }
        this.algorithmName = algorithmName;
        this.iterations = Math.max(DEFAULT_ITERATIONS,  hashIterations);
        ByteSource saltBytes = null;
        if (salt != null) {
            saltBytes = convertSaltToBytes(salt);
            this.salt = saltBytes;
        }
        ByteSource sourceBytes = convertSourceToBytes(source);
        hash(sourceBytes, saltBytes, hashIterations);
    }

 

 

測試加密:

     public static void main(String[] args) {
           String hash="MD5";
           Object cred = "123456";
           Object salt = null;
           int hashInter = 1024;
           //加密的類
           System.out.println(new SimpleHash(hash, cred, salt,  hashInter));
     }

 

fc1709d0a95a6be30bc5926fdb7f22f4

 

 

MD5鹽值加密

假設兩個人原始密碼一致,這樣也會更加安全
所以此時需要使用到鹽值
 
步驟:
doGetAuthenticationInfo的方法返回值創建 SimpleAuthenticationInfo對象的時候
使用 SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
      //鹽值
           ByteSource credentialsSalt =  ByteSource.Util.bytes(username);

 

使用ByteSource.Util.bytes()來計算鹽值
鹽值需要唯一一般使用隨機字符串或userid
使用      new SimpleHash(algorithmName, source, salt, hashIterations)計算鹽值解密后的鹽值

 

此時放置的不在是明文的密碼

ShiroRealm.java

 //6.根據用戶的情況來構建AuthenticationInfo並且返回
           //以下信息是從數據庫中獲取的
           //principal:認證的實體信息,可以是username,也可以是數據表對應的實體對象
           Object principal = username;
           //credentials:密碼
           Object credentials = null; if("user".equals(username)){ //計算后user密碼為123456的鹽值 credentials = "2044dc18864ca3bc408359a0fb13c2a7"; }else if("admin".equals(username)){ //計算和admin密碼為123456的鹽值 credentials = "30beaf2a87d54ebe889cfccc076247ad";  }  
           //realmName:當前realm對象為name,調用父類的getName()方法即可
           String realmName = getName();
           
           //鹽值
           ByteSource credentialsSalt = ByteSource.Util.bytes(username);
          
           SimpleAuthenticationInfo info = null;//new  SimpleAuthenticationInfo(principal, credentials, realmName);
           info = new SimpleAuthenticationInfo(principal,  credentials, credentialsSalt, realmName);
           return info;
     }

 

鹽值的計算:

public static void main(String[] args) {
           String hash="MD5";
           Object cred = "123456";
           Object salt = "admin";
           int hashInter = 20;
           //加密的類
           System.out.println(new SimpleHash(hash, cred, salt, hashInter));
           //new SimpleHash(algorithmName, source, salt,  hashIterations)
     }

 

在測試中,只有用戶名為user/admin 密碼為123456才能成功登陸

 

 

 多Realm

 創建新的類

 

 SecondRealm。java

public class SecondRealm extends AuthenticatingRealm {
     @Override
     protected AuthenticationInfo  doGetAuthenticationInfo(AuthenticationToken arg0) throws  AuthenticationException {
           System.out.println("SecondRealm-->");
           
           //1.把AuthenticationToken轉為UsernamePasswordToken
           UsernamePasswordToken  upToken =  (UsernamePasswordToken) arg0;
           
           //2.從UsernamePasswordToken獲取username
           String username = upToken.getUsername();
           
           //3.調用數據庫的方法,從數據庫查詢username對應的用戶記錄
           System.out.println("從數據庫中獲取username:" +  username);
           
           //4.若用戶不存在可以拋出異常 UnKnownAccountException異常
           if("unknow".equals(username)){
                throw new UnknownAccountException("username 不存在");
           }
           //5.根據用戶信息的清空決定是否需要拋出其他的異常
           if("monster".equals(username)){
                throw new LockedAccountException("用戶被鎖定");
           }
           //6.根據用戶的情況來構建AuthenticationInfo並且返回
           //以下信息是從數據庫中獲取的
           //principal:認證的實體信息,可以是username,也可以是數據表對應的實體對象
           Object principal = username;
           //credentials:密碼
           Object credentials = null;
           if("user".equals(username)){
                credentials =  "6e3be0247455b9298f47eac8e57a07214ef84115";
           }else if("admin".equals(username)){
                credentials =  "ff9633d047eaaf9861984ed86e5f73f904647716";
           }
           
           //realmName:當前realm對象為name,調用父類的getName()方法即可
           String realmName = getName();
           
           //鹽值
           ByteSource credentialsSalt =  ByteSource.Util.bytes(username);
           
           SimpleAuthenticationInfo info = null;//new  SimpleAuthenticationInfo(principal, credentials, realmName);
           info = new SimpleAuthenticationInfo(principal,  credentials, credentialsSalt, realmName);
           return info;
     }
     
     public static void main(String[] args) {
           String hash="SHA1";
           Object cred = "123456";
           Object salt = "user";
           int hashInter = 20;
           //加密的類
           System.out.println(new SimpleHash(hash, cred, salt,  hashInter));
           //new SimpleHash(algorithmName, source, salt,  hashIterations)
     }
     
     
}

 

加密方式是SHA1

 

在applicationContext.xml
需要注釋一個
     <!--
      1.配置SecurityManager
      -->
    <bean id="securityManager"  class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
      
        <property name="cacheManager" ref="cacheManager"/>
      
      <!-- 此時這個屬性需要注釋使用下面的屬性配置 <property name="realm" ref="jdbcRealm"/> -->
        <property name="authenticator"  ref="autheniicator"></property>
        
    </bean>

 

     <!-- 認證器 -->
         <bean id="autheniicator"  class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <property name="realms"> <list> <ref bean="jdbcRealm"/> <ref bean="SecondRealm"/> </list> </property>
         </bean>
         
         <!--
            3.配置Realm
            3.1直接實現Realm接口的bean
          -->
    <bean id="jdbcRealm"  class="com.MrChengs.shiro.realms.ShiroRealm">
        <property name="credentialsMatcher">
            <bean  class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                 
                 <!-- 加密的方法 -->
                 <property name="hashAlgorithmName" value="MD5"></property>
                 
                 <!-- 指定加密的次數 -->
                 <property name="hashIterations"  value="20"></property>
            </bean>
        </property>
    </bean>
    
    <bean id="SecondRealm"  class="com.MrChengs.shiro.realms.SecondRealm">
        <property name="credentialsMatcher">
            <bean  class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                 
                 <!-- 加密的方法 -->
                 <property name="hashAlgorithmName" value="SHA1"></property>
                 
                 <!-- 指定加密的次數 -->
                 <property name="hashIterations"  value="20"></property>
            </bean>
        </property>
    </bean>

 

執行的順序和list的順序有關

<bean id="autheniicator"  class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <property name="realms">
       <list> <ref bean="jdbcRealm"/> <ref bean="SecondRealm"/> </list>
            </property>
         </bean>

 


免責聲明!

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



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