Shiro学习(五) 您所在的位置:网站首页 java文件的加密和解密程序是什么 Shiro学习(五)

Shiro学习(五)

2024-07-04 09:28| 来源: 网络整理| 查看: 265

前言

前面几篇文章的密码都是以明文形式存储。在真实项目中当然不可能明文存储密码,密码一定是以加密的形式存储的。前面我们可以看到当我们给出帐号和密码后,shiro就会去查找ini配置文件或者数据库对应字段来匹配账号密码。那如果我们把存储的密码加密,shiro又如何根据我们提交的明文密码与存储的加密密码匹配呢?

Shiro加密与匹配的原理

这里不准备展示源码。相信很多读者看文章时面对大量源码也看得一头雾水,并不能总结出什么来,所以这里大致讲讲思路,有兴趣的读者可以自行跟踪源码。这里以读取ini文件为例:

1、当我们使用subject.login(token)这个命令时,会调用IniRealm的父类SimpleAccountRealm的doGetAuthenticationInfo获取存储的认证信息。PS:如果我们自定义realm的话,如何获取认证通常也是重写这个方法。

2、通过AuthenticatingRealm的assertCredentialsMatch方法对比我们提交的帐号密码token与上一步获取的认证信息是否匹配。如果匹配就返回认证信息,否则就抛出异常。

3、第2步匹配的方法调用CredentialsMatcher接口的doCredentialsMatch方法。例如默认的匹配类为SimpleCredentialsMatcher,它的doCredentialsMatch非常简单,就是比较提交的密码与第1步获取的认证密码是否一致。这过程没做任何加密解密处理。所以对于加密或者解密操作,最主要的实现在doCredentialsMatch方法上进行。

shiro本身提供了一些加密解密的类和方法,例如PasswordMatcher类,当然也可以自定义,只需配置到securityManager中即可。

配置加密解密类

匹配类

shiro默认的匹配类是SimpleCredentialsMatcher。读者可以参考下其源码,实现非常简单。shiro提供的匹配接口是CredentialsMatcher,只要实现doCredentialsMatch方法即可:

public interface CredentialsMatcher { boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info); }

加密与验证服务

shiro提供了加密与验证服务的接口PasswordService接口:

public interface PasswordService { String encryptPassword(Object plaintextPassword) throws IllegalArgumentException; boolean passwordsMatch(Object submittedPlaintext, String encrypted); }

第一个方式用于加密,第二个方法用于进行对密码进行匹配。shiro自身提供的加密解密类都实现了这个接口。通常这个接口是配合CredentialsMatcher使用的。一般CredentialsMatcher的doCredentialsMatch方法对提交的帐号密码与存储的帐号密码信息进行一些处理,后面再调用PasswordService的passwordsMatch方法进行匹配。

为什么有CredentialsMatcher还要设计PasswordService呢?

我的理解,只用CredentialsMatcher也可以。默认匹配类SimpleCredentialsMatcher就没有使用PasswordService。CredentialsMatcher接口doCredentialsMatch传入的参数是AuthenticationToken(用户登录提交的帐号密码信息)和AuthenticationInfo(系统存储的帐号密码信息),我们可以在doCredentialsMatch中提取并组合后放到PasswordService的passwordsMatch中处理。把PasswordService提出来可以更方便替换不同的加密算法。

代码示例

现在做一个简单的例子,展示一下PasswordService和CredentialsMatcher怎么使用。shiro默认的CredentialsMatcher是PasswordMatcher,默认的PasswordService是DefaultPasswordService。即使我们不设置也行,但例子中还是希望手动设置,让读者更好理解。

首先我们先得到一个加密的密码:

public class PassWordCrypto { public static String encriptPassword(String password) { PasswordService service = new DefaultPasswordService(); return service.encryptPassword(password); } public static void main(String[] args) { System.out.println(encriptPassword("123")); } }

执行上面那段代码,得到密码“123”加密结果为$shiro1$SHA-256$500000$3mRjauseIWB330SU++9msA==$eHTXKKktQduiDi6Kut8HzwBJHeiwx7pXDemieEhgDkE=

 

我们本次以ini位置文件为例子,创建password.ini,并把刚才得到的加密密码填入:

[main] passwordMatcher=org.apache.shiro.authc.credential.PasswordMatcher passwordService=org.apache.shiro.authc.credential.DefaultPasswordService passwordMatcher.passwordService=$passwordService iniRealm.credentialsMatcher=$passwordMatcher securityManager.realms=$iniRealm [users] zhang=$shiro1$SHA-256$500000$3mRjauseIWB330SU++9msA==$eHTXKKktQduiDi6Kut8HzwBJHeiwx7pXDemieEhgDkE=,role1 li=123 [roles] role1=user:create,update role2=user:create,delete

上面[main]中把DefaultPasswordService设置到PasswordMatcher中,再把PasswordMatcher设置到iniRealm中。这里的iniRealm是默认创建出来的,如果我们自己新建一个IniRealm设置进去的话反而会报错。

接着写测试代码:

package com.sadoshi.shiro.crypto; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.env.BasicIniEnvironment; import org.apache.shiro.env.Environment; import org.apache.shiro.subject.Subject; import org.junit.Before; import org.junit.Test; public class PasswordServiceTest { private Subject subject; @Before public void init() { Environment env = new BasicIniEnvironment("classpath:password.ini"); org.apache.shiro.mgt.SecurityManager securityManager = env.getSecurityManager(); SecurityUtils.setSecurityManager(securityManager); subject = SecurityUtils.getSubject(); } @Test public void hashCrypto() { UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); System.out.println("ok"); } catch (AuthenticationException e) { e.printStackTrace(); } subject.logout(); } }

如果密码对不上,就会抛出异常。我们这里执行结果正确。

小结

本文只是初步展示一下CredentialsMatcher和PasswordService是怎么使用的。后面的文章还会展示其他加密方式。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有