zoukankan      html  css  js  c++  java
  • Shiro——MD5加密

    一、shiro默认密码的比对

    通过 AuthenticatingRealm credentialsMatcher 属性来进行的密码的比对

    /**源码org.apache.shiro.realm.AuthenticatingRealm
    * Asserts that the submitted {@code AuthenticationToken}'s credentials match the stored account
    * {@code AuthenticationInfo}'s credentials, and if not, throws an {@link AuthenticationException}.
    *
    * @param token the submitted authentication token
    * @param info  the AuthenticationInfo corresponding to the given {@code token}
    * @throws AuthenticationException if the token's credentials do not match the stored account credentials.
    */
        protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) 
        throws AuthenticationException { CredentialsMatcher cm = getCredentialsMatcher(); if (cm != null) { if (!cm.doCredentialsMatch(token, info)) { //not successful - throw an exception to indicate this: String msg = ""; throw new IncorrectCredentialsException(msg); } } else { throw new AuthenticationException(""); } }

    调试技巧:在org.apache.shiro.authc.UsernamePasswordToken的getPassword()方法中添加断点

    ①、接口CredentialsMatcher

    源码
    package org.apache.shiro.authc.credential;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    
    public interface CredentialsMatcher {
    
        boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
    
    }

    ②、接口CredentialsMatcher的继承关系

     shiro默认是用org.apache.shiro.authc.credential.SimpleCredentialsMatcher进行密码比较

    //SimpleCredentialsMatcher.doCredentialsMatch()
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { Object tokenCredentials = getCredentials(token); Object accountCredentials = getCredentials(info); return equals(tokenCredentials, accountCredentials); }

    二、MD5加密

    使用 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations) 来计算盐值加密后的密码的值

    import org.apache.shiro.crypto.hash.SimpleHash;

    import org.apache.shiro.util.ByteSource;
    public static void  main(String[] args){
            //加密方式
            String hashAlgorithmName = "MD5";
            //明文密码
            Object credentials = "1234";
            //盐值
            Object salt = ByteSource.Util.bytes("nchu");
            int hashIterations = 1024;
    
            Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
         //加密后的密码 System.out.println(result); }

    三、Shiro密码加密

    ①、在spring核心配置文件中配置自定义Realm

        <!-- 自定义Realm -->
        <bean id="MD5Realm" class="com.nchu.shiro.MD5Realm">
           <!-- 更改自定义Realm的默认credentialsMatcher属性-->
            <property name="credentialsMatcher" >
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <!--指定加密算法-->
                    <property name="hashAlgorithmName" value="MD5"></property>
                    <!--设置加密次数-->
                    <property name="hashIterations" value="1024"></property>
                </bean>
            </property>
        </bean>
        <!-- 安全管理器 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realms">
                <list>
                    <ref bean="MD5Realm"/>
                </list>
            </property>
        </bean>

    替换当前 Realm 的 credentialsMatcher 属性. 直接使用 HashedCredentialsMatcher 对象, 并设置加密算法即可

    ②、自定义Realm

    使用shiro MD5加密前提数据库存储的密码是经过MD5加密的

    import com.nchu.mvc.dao.ShiroRealmMapper;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.realm.AuthenticatingRealm;
    import org.apache.shiro.util.ByteSource;
    import org.springframework.beans.factory.annotation.Autowired;
    
    /**
     * Created by yangshijing on 2018/1/16 0016.
     */
    public class MD5Realm extends AuthenticatingRealm {
        @Autowired
        ShiroRealmMapper shiroRealmMapper;
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("----->"+token.hashCode());
            //1. 把 AuthenticationToken 转换为 UsernamePasswordToken
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    
            //2. 从 UsernamePasswordToken 中来获取 username
            String username = upToken.getUsername();
    
            //3. 调用数据库的方法, 从数据库中查询 username 对应的用户记录
    
            System.out.println("从数据库中获取 username: " + username + " 所对应的用户信息.");
            String password  = shiroRealmMapper.login(username);
            //4. 若用户不存在, 则可以抛出 UnknownAccountException 异常
            if(password==null){
                throw new UnknownAccountException("用户不存在!");
            }
    
            //5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.
            /*  if("monster".equals(username)){
                throw new LockedAccountException("用户被锁定");
            }*/
            //6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 
         //通常使用的实现类为: SimpleAuthenticationInfo
    //以下信息是从数据库中获取的. //1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象. Object principal = username; //2). hashedCredentials: 加密后的密码. Object hashedCredentials = password; //3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可 String realmName = getName(); //4). 加密盐值 ByteSource credentialsSalt = ByteSource.Util.bytes("nchu"); SimpleAuthenticationInfo info = //new SimpleAuthenticationInfo(principal, credentials, realmName); new SimpleAuthenticationInfo(principal,hashedCredentials,credentialsSalt,realmName); return info; }

    注意:在 doGetAuthenticationInfo 方法返回值创建 SimpleAuthenticationInfo 对象的时候, 需要使用SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName) 构造器

  • 相关阅读:
    利用connect建立前端开发服务器
    Bootstrap Popover 隐藏的Javasript方法
    Kafka 2.1.0压缩算法性能测试
    关于Kafka java consumer管理TCP连接的讨论
    Java API获取consumer group最新提交位移的时间
    关于Kafka producer管理TCP连接的讨论
    【译】Apache Kafka支持单集群20万分区
    关于Kafka broker IO的讨论
    Kafka 2.0 ConsumerGroupCommand新功能
    关于Kafka high watermark的讨论2
  • 原文地址:https://www.cnblogs.com/realshijing/p/8302489.html
Copyright © 2011-2022 走看看