Shiro的使用(二)—使用MD5Hash完成认证(MD5加密)

Shiro的使用(二)—使用MD5Hash完成认证(MD5加密)

1、MD5Hash的使用问题

问题:在开发的时候、敏感信息在数据库是如何存储的?

  • 敏感信息在数据库存储的时候都不能存储明文
  • 一部分就类似于密码这种,不需要知道这个值本身是多少(散列)
    • MD5 SHA1
  • 另外一部分:需要知道这个值 是多少(加密、解密)
    • DES AES 3DES RSA

在shiro框架中, 也提供了 密码散列的功能

2、使用MD5Hash完成认证

2.1、简单使用 Md5Hash
 public static void main(String[] args){
 		// 直接散列
        Md5Hash md5Hash0 = new Md5Hash("abc");
        System.out.println("散列后的结果:"+md5Hash0);
        
        // 为什么要加盐?  
        // 为了让密码更加安全  更加不容易被破解

        Md5Hash md5Hash1 = new Md5Hash("abc", "123");
        System.out.println("加盐散列之后的值:"+md5Hash1);

        Md5Hash md5Hash2 = new Md5Hash("123abc");
        System.out.println("加盐散列之后的值:"+md5Hash2);
        System.out.println("md5Hash2 == md5Hash1 : " + md5Hash2  == md5Hash1);


        // param1:密码;param2:盐;param3:散列次数
        Md5Hash md5Hash = new Md5Hash("123", "", 2);
        System.out.println("加盐+次数构成的值:"+md5Hash);

        Md5Hash md5Hash3 = new Md5Hash("123");
        Md5Hash md5Hash4 = new Md5Hash(md5Hash3);
        System.out.println("md5Hash == md5Hash4 : " + md5Hash == md5Hash4);
    }
2.2、搭建测试环境
2.2.1、修改数据库
  1. 增加password的长度(要满足可以填充密码散列后的值)
  2. 添加一个盐的字段

在这里插入图片描述

2.2.2、将数据库的密码改成盐+密码散列后的值
Md5Hash md5Hash1 = new Md5Hash("123", "111");
System.out.println("加盐散列之后的值:" + md5Hash1);
2.2.3、修改pom.xml

其他必须依赖请自行导入,或参照 shiro的使用(一)权限管理—shiro的简单使用

<!-- 添加访问数据库的依赖 -->
		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
2.2.4、修改user.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 4026322871228725196L;
    private Integer id;
    private String name;
    private String password;
    private String salt;
}
2.2.5、编写JdbcUtils.java
public class JdbcUtils {
    private static DruidDataSource dataSource;
    static {
        dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///demo");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
    }
    /**
     * 返回操作数据库的对象
     */
    public static QueryRunner getQueryRunner(){
        return new QueryRunner(dataSource);
    }
}
2.2.6、编写UserDao.java
public class UserDao {
    public User getUserByName(String name) throws SQLException {
        QueryRunner queryRunner = JdbcUtils.getQueryRunner();
        return queryRunner.query("select * from user where name = ?", new BeanHandler<>(User.class), name);
    }
}
2.2.7、编写配置文件

shiro-hash.ini resources文件夹下

[main]
# 定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
# 散列算法
credentialsMatcher.hashAlgorithmName=md5
# 散列次数
credentialsMatcher.hashIterations=1

# 将凭证匹配器设置到realm
customRealm=com.fu.shiro.realm.UserRealm
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
2.3、编写UserRealm.java
public class UserRealm extends AuthorizingRealm {

    private UserDao userDao = new UserDao();

    @Override
    public String getName() {
        return "UserRealm";
    }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //第一步:通过token获取到用户数据
        String userName = (String) authenticationToken.getPrincipal();
        //第二步:通过用户名 去数据库查询用户对象
        User user = null;
        try {
            user = userDao.getUserByName(userName);
            System.out.println("从数据库里查询出来的数据是:" + user);
        } catch (Exception e) {
            System.out.println("查询失败: " + e.fillInStackTrace());
        }
        if (null == user) { // 如果数据库中没有该数据
            return null;
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}
2.4、测试
	@Test
    public void userRealmTest() {
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-hash.ini");
        SecurityManager securityManager = iniSecurityManagerFactory.createInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("kongming", "123");
        subject.login(token);
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
        // 用户退出
        subject.logout();
        // 再次打印用户认证状态
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值