【Shiro】第三章 Shiro入门(三)

简介: 【Shiro】第三章 Shiro入门(三)

【1.4】新建ClientTest

1. package com.itheima.shiro.client;
2. 
3. import com.itheima.shiro.tools.EncodesUtil;
4. import org.junit.Test;
5. 
6. /**
7.  * @Description:测试
8.  */
9. public class ClientTest {
10. 
11. /**
12.      * @Description 测试16进制编码
13.      */
14. @Test
15. public void testHex(){
16. String val = "holle";
17. String flag = EncodesUtil.encodeHex(val.getBytes());
18. String valHandler = new String(EncodesUtil.decodeHex(flag));
19.         System.out.println("比较结果:"+val.equals(valHandler));
20.     }
21. 
22. /**
23.      * @Description 测试base64编码
24.      */
25. @Test
26. public void testBase64(){
27. String val = "holle";
28. String flag = EncodesUtil.encodeBase64(val.getBytes());
29. String valHandler = new String(EncodesUtil.decodeBase64(flag));
30.         System.out.println("比较结果:"+val.equals(valHandler));
31.     }
32. 
33. 
34. }

【1.5】小结

1. 1、shiro目前支持的编码与解码:
2.  base64
3.    (HEX)16进制字符串
4. 2、那么shiro的编码与解码什么时候使用呢?又是怎么使用的呢?

【2】散列算法

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些md5解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如salt(即盐);这样散列的对象是“密码+salt”,这样生成的散列值相对来说更难破解。

shiro支持的散列算法:

Md2Hash、Md5Hash、Sha1Hash、Sha256Hash、Sha384Hash、Sha512Hash

【2.1】新增DigestsUtil

1. package com.itheima.shiro.tools;
2. 
3. import com.sun.org.apache.bcel.internal.generic.NEW;
4. import org.apache.shiro.crypto.SecureRandomNumberGenerator;
5. import org.apache.shiro.crypto.hash.SimpleHash;
6. import sun.security.util.Password;
7. 
8. import java.util.HashMap;
9. import java.util.Map;
10. 
11. /**
12.  * @Description:摘要
13.  */
14. public class DigestsUtil {
15. 
16. private static final String SHA1 = "SHA-1";
17. 
18. private static final Integer ITERATIONS =512;
19. 
20. /**
21.      * @Description sha1方法
22.      * @param input 需要散列字符串
23.      * @param salt 盐字符串
24.      * @return
25.      */
26. public static String sha1(String input, String salt) {
27. return new SimpleHash(SHA1, input, salt,ITERATIONS).toString();
28.     }
29. 
30. /**
31.      * @Description 随机获得salt字符串
32.      * @return
33.      */
34. public static String generateSalt(){
35. SecureRandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
36. return randomNumberGenerator.nextBytes().toHex();
37.     }
38. 
39. 
40. /**
41.      * @Description 生成密码字符密文和salt密文
42.      * @param
43.      * @return
44.      */
45. public static Map<String,String> entryptPassword(String passwordPlain) {
46.        Map<String,String> map = new HashMap<>();
47. String salt = generateSalt();
48. String password =sha1(passwordPlain,salt);
49.        map.put("salt", salt);
50.        map.put("password", password);
51. return map;
52.     }
53. }

【2.2】新增ClientTest

1. package com.itheima.shiro.client;
2. 
3. import com.itheima.shiro.tools.DigestsUtil;
4. import com.itheima.shiro.tools.EncodesUtil;
5. import org.junit.Test;
6. 
7. import java.util.Map;
8. 
9. /**
10.  * @Description:测试
11.  */
12. public class ClientTest {
13. 
14. /**
15.      * @Description 测试16进制编码
16.      */
17. @Test
18. public void testHex(){
19. String val = "holle";
20. String flag = EncodesUtil.encodeHex(val.getBytes());
21. String valHandler = new String(EncodesUtil.decodeHex(flag));
22.         System.out.println("比较结果:"+val.equals(valHandler));
23.     }
24. 
25. /**
26.      * @Description 测试base64编码
27.      */
28. @Test
29. public void testBase64(){
30. String val = "holle";
31. String flag = EncodesUtil.encodeBase64(val.getBytes());
32. String valHandler = new String(EncodesUtil.decodeBase64(flag));
33.         System.out.println("比较结果:"+val.equals(valHandler));
34.     }
35. 
36. @Test
37. public void testDigestsUtil(){
38.        Map<String,String> map =  DigestsUtil.entryptPassword("123");
39.         System.out.println("获得结果:"+map.toString());
40.     }
41. 
42. }

4、Realm使用散列算法

上面我们了解编码,以及散列算法,那么在realm中怎么使用?在shiro-day01-02realm中我们使用的密码是明文的校验方式,也就是SecurityServiceImpl中findPasswordByLoginName返回的是明文123的密码

1. package com.itheima.shiro.service.impl;
2. 
3. import com.itheima.shiro.service.SecurityService;
4. 
5. /**
6.  * @Description:权限服务层
7.  */
8. public class SecurityServiceImpl implements SecurityService {
9. 
10. @Override
11. public String findPasswordByLoginName(String loginName) {
12. return "123";
13.     }
14. }

【1】新建项目

shiro-day01-05-ciphertext-realm

【2】创建密文密码

使用ClientTest的testDigestsUtil创建密码为“123”的password密文和salt密文

1. password:56265d624e484ca62c6dfbc523e6d6fc7932d0d5
2. salt:845a66ac80174c0e486db9354cf84f9a

【3】修改SecurityService

SecurityService修改成返回salt和password的map

1. package com.itheima.shiro.service;
2. 
3. import java.util.Map;
4. 
5. /**
6.  * @Description:权限服务接口
7.  */
8. public interface SecurityService {
9. 
10. /**
11.      * @Description 查找密码按用户登录名
12.      * @param loginName 登录名称
13.      * @return
14.      */
15.     Map<String,String> findPasswordByLoginName(String loginName);
16. }
1. package com.itheima.shiro.service.impl;
2. 
3. import com.itheima.shiro.service.SecurityService;
4. 
5. import java.util.HashMap;
6. import java.util.Map;
7. 
8. /**
9.  * @Description:权限服务层
10.  */
11. public class SecurityServiceImpl implements SecurityService {
12. 
13. @Override
14. public Map<String,String> findPasswordByLoginName(String loginName) {
15. //模拟数据库中存储的密文信息
16. return  DigestsUtil.entryptPassword("123");
17.     }
18. }

【4】指定密码匹配方式

为DefinitionRealm类添加构造方法如下:

1. /**
2.      * @Description 构造函数
3.      */
4. public DefinitionRealm() {
5. //指定密码匹配方式为sha1
6. HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
7. //指定密码迭代次数
8.     matcher.setHashIterations(DigestsUtil.ITERATIONS);
9. //使用父亲方法使匹配方式生效
10.     setCredentialsMatcher(matcher);
11. }

修改DefinitionRealm类的认证doGetAuthenticationInfo方法如下

1. /**
2.      * @Description 认证接口
3.      * @param token 传递登录token
4.      * @return
5.      */
6. @Override
7. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
8. //从AuthenticationToken中获得登录名称
9. String loginName = (String) token.getPrincipal();
10. SecurityService securityService = new SecurityServiceImpl();
11.     Map<String, String> map = securityService.findPasswordByLoginName(loginName);
12. if (map.isEmpty()){
13. throw new UnknownAccountException("账户不存在");
14.     }
15. String salt = map.get("salt");
16. String password = map.get("password");
17. //传递账号和密码:参数1:缓存对象,参数2:明文密码,参数三:字节salt,参数4:当前DefinitionRealm名称
18. return  new SimpleAuthenticationInfo(loginName,password, ByteSource.Util.bytes(salt),getName());
19. }

【5】测试

相关文章
|
9月前
|
缓存 数据库 数据安全/隐私保护
【Shiro】第三章 Shiro入门(四)
【Shiro】第三章 Shiro入门(四)
55 0
|
9月前
|
存储 算法 程序员
【Shiro】第三章 Shiro入门(二)
【Shiro】第三章 Shiro入门(二)
56 1
|
9月前
|
安全 数据安全/隐私保护
【Shiro】第三章 Shiro入门(一)
【Shiro】第三章 Shiro入门
53 1
|
9月前
|
存储 缓存 安全
【Shiro】第二章 Shiro概述
【Shiro】第二章 Shiro概述
61 0
|
9月前
|
存储 缓存 安全
Shiro学习之Shiro简介
Shiro学习之Shiro简介
71 0
|
9月前
|
Java API 数据库
Shiro学习之Shiro基本使用(1)
Shiro学习之Shiro基本使用(1)
63 0
|
9月前
|
Java 数据库 数据安全/隐私保护
Shiro学习之Shiro基本使用(2)
Shiro学习之Shiro基本使用(2)
39 0
|
存储 数据采集 缓存
Shiro简介
.什么是Shiro - .ApacheShiro 是一个Java的安全(权限)框架。 - .Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。 - .Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等。
Shiro简介
|
存储 缓存 安全
shiro实战教程(一)
shiro实战教程(一)
126 0
shiro实战教程(一)
|
Java 网络安全 数据库
shiro实战教程(二)
shiro实战教程(二)
195 1
shiro实战教程(二)