0


Spring Boot学习篇(十)

Spring Boot学习篇(十)

shiro安全框架使用篇(二)——登录实例(密码以密文方式存储,不含记住密码)

1.模拟注册时,生成密文到数据库中

1.1 在zlz包下创建util包,并在下面创建SHAUtil01类(初始里面无方法)和SHAUtil02类,其目录结构如下所示

在这里插入图片描述

1.2 两种生成密文的方式
1.2.1 自己指定盐
a 核心代码
publicstaticStringshaPassword(String oldPwd,String salt){returnnewSimpleHash("sha-256",oldPwd,salt,100).toString();}
b 完整代码
packagecom.zlz.util;importorg.apache.shiro.crypto.hash.SimpleHash;importjava.util.Random;publicclassSHAUtil01{/**
     * 对密码使用sha256算法的方式加密
     * 加密不可逆: 无法通过新生成密文来反推出原来的密码
     * 盐是为了提高密码的安全系数的 随机生成的
     * 实际是拿你随机生成的盐和原来的字符串拼接在一起在来生成密文
     * 一般是可以使用随机字符串来表示盐的
     * hashIteration 表示加密计算的次数(拿盐和字符串拼接的次数) 散列次数越多 安全系越高
     * @param oldPwd 原密码
     * @param salt  盐
     * @return
     */publicstaticStringshaPassword(String oldPwd,String salt){returnnewSimpleHash("sha-256",oldPwd,salt,100).toString();}publicstaticvoidmain(String[] args){//想要对admin这个密码进行加密.sha-256是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次//注意这个盐是建议每个账户一个,尽量不要重复String newPwd =SHAUtil01.shaPassword("admim","q1");System.out.println(newPwd);}}
1.2.2 随机生成盐
a 核心代码
//①定义一个随机生成10位含字母数字符号的盐staticRandom random=newRandom();publicstaticStringgetSalt(){//盐从以下这些字符中去随机取出10个出来,下面盐的字符串是可以自定义的,专门弄一个方法拿到盐String salts="ewsfjbwdufgsfsnuivhe123456789/*;[]";StringBuffer salt=newStringBuffer();for(int i =1; i <=10; i++){//charAt是取出索引处的字符char c=salts.charAt(random.nextInt(salts.length()));
        salt.append(String.valueOf(c));}return salt.toString();}//②sha-256的加密方式(不可逆的)进行加密得到密文publicstaticStringshaPassword(String oldPwd){returnnewSimpleHash("sha-256",oldPwd,getsalt(),100).toString();}
b 完整代码
packagecom.zlz.util;importorg.apache.shiro.crypto.hash.SimpleHash;importjava.util.Random;publicclassSHAUtil02{/**
     * 对密码使用sha-256算法的方式加密
     * 加密不可逆: 无法通过新生成密文来反推出原来的密码
     *
     * 盐是为了提高密码的安全系数的 随机生成的
     * 实际是拿你随机生成的盐和原来的字符串拼接在一起在来生成密文
     * 一般是可以使用随机字符串来表示盐的
     * hashIteration 表示加密计算的次数(拿盐和字符串拼接的次数) 散列次数越多 安全系越高
     * @param oldPwd 原密码
     * @return 字符串形式的密文
     */publicstaticStringshaPassword(String oldPwd){returnnewSimpleHash("sha-256",oldPwd,getSalt(),100).toString();}staticRandom random=newRandom();publicstaticStringgetSalt(){//盐从以下这些字符中去随机取出10个出来,下面盐的字符串是可以自定义的,专门弄一个方法拿到盐String salts="ewsfjbwdufgsfsnuivhe123456789/*;[]";StringBuffer salt=newStringBuffer();for(int i =1; i <=10; i++){//charAt是取出索引处的字符char c=salts.charAt(random.nextInt(salts.length()));
            salt.append(String.valueOf(c));}return salt.toString();}publicstaticvoidmain(String[] args){//想要对admin这个密码进行加密.sha-256是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次String newPwd =SHAUtil02.shaPassword("admin");System.out.println(newPwd);}}
1.3 手动变更数据表(以自己指定盐的方式)
1.3.1 生成账户"admin"所对应的密文
a 测试代码
publicstaticvoidmain(String[] args){//想要对admin这个密码进行加密.是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次String newPwd =SHAUtil01.shaPassword("admin","q1");System.out.println(newPwd);}
b 运行截图

在这里插入图片描述

1.3.2 账户"aaa"所对应的密文
a 测试代码
publicstaticvoidmain(String[] args){//想要对admin这个密码进行加密.是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次String newPwd =SHAUtil01.shaPassword("aaa","q2");System.out.println(newPwd);}
b 运行截图

在这里插入图片描述

1.3.3 账户"bbb"所对应的密文
a 测试代码
publicstaticvoidmain(String[] args){//想要对admin这个密码进行加密.是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次String newPwd =SHAUtil01.shaPassword("bbb","q3");System.out.println(newPwd);}
b 运行截图

在这里插入图片描述

1.3.4 手动更改sys_user表的salt字段,更改后的效果如下所示

在这里插入图片描述

1.4 sys_user表所对应的sql语句(生成对应密文后的版本)
/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3305
 Source Server Type    : MySQL
 Source Server Version : 80030
 Source Host           : 127.0.0.1:3305
 Source Schema         : db0618

 Target Server Type    : MySQL
 Target Server Version : 80030
 File Encoding         : 65001

 Date: 15/01/2023 22:21:15
*/SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS =0;-- ------------------------------ Table structure for sys_user-- ----------------------------DROPTABLEIFEXISTS`sys_user`;CREATETABLE`sys_user`(`id`intNOTNULL,`username`varchar(100)CHARACTERSET utf8mb3 COLLATE utf8mb3_general_ci NULLDEFAULTNULL,`password`varchar(100)CHARACTERSET utf8mb3 COLLATE utf8mb3_general_ci NULLDEFAULTNULL,`salt`varchar(100)CHARACTERSET utf8mb3 COLLATE utf8mb3_general_ci NULLDEFAULTNULL,`suo`intNULLDEFAULT0,PRIMARYKEY(`id`)USINGBTREE)ENGINE=InnoDBCHARACTERSET= utf8mb3 COLLATE= utf8mb3_general_ci ROW_FORMAT = COMPACT;-- ------------------------------ Records of sys_user-- ----------------------------INSERTINTO`sys_user`VALUES(1,'admin','7e84f2fbdc9de493dc1e17c44b163ebc9168bc472f26db231f472f1012e62d87','q1',0);INSERTINTO`sys_user`VALUES(2,'aaa','18ae76b69e6b7b2ae78100013442beafb692bbbad663b1ff5845f0036b446ad7','q2',0);INSERTINTO`sys_user`VALUES(3,'bbb','7c8425aa02dfdfc973257f3b2a4ded786eadee830d7a29a900669727fa7a5966','q3',1);SET FOREIGN_KEY_CHECKS =1;

2 在config包下创建域(MysqlRealm类)

packagecom.zlz.config;importcom.zlz.entity.SysUser;importcom.zlz.mapper.SysUserMapper;importorg.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.apache.shiro.util.ByteSource;importorg.springframework.beans.factory.annotation.Autowired;publicclassMysqlRealmextendsAuthorizingRealm{//授权方法@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollection pc){returnnull;}@AutowiredSysUserMapper sysUserMapper;//认证方法@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationToken at)throwsAuthenticationException{//①在认证方法里面获取输入的用户名String username =(String) at.getPrincipal();SysUser user = sysUserMapper.findUserByUsername(username);if(user ==null){//②如果账户不存在,就抛出账户不存在异常thrownewUnknownAccountException();}//③检查账户是否锁定 如果锁定的话,那就会抛出锁定异常if(user.getSuo()==1){thrownewLockedAccountException();}//密码错误,shiro会自动帮你抛出密码错误这个异常的//        System.out.println("实例对象名称:");//④拿到盐(放在第三个形参的位置)-----变动的地方ByteSource salt =ByteSource.Util.bytes(user.getSalt());//⑤把对应的参数设置进去SimpleAuthenticationInfo s=newSimpleAuthenticationInfo(user.getUsername(),user.getPassword(),salt,getName());return s;}}

3.在config包下创建ShiroConfig类(进行shiro的相关配置)

packagecom.zlz.config;importorg.apache.shiro.authc.credential.HashedCredentialsMatcher;importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;importorg.apache.shiro.web.session.mgt.DefaultWebSessionManager;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassShiroConig{//安全管理器的配置@BeanpublicDefaultWebSecurityManagersecurityManager(){DefaultWebSecurityManager dws=newDefaultWebSecurityManager();
        dws.setRealm(mysqlRealm());//设置会话管理器,保证第一次访问的时候不会出错
        dws.setSessionManager(newDefaultWebSessionManager());return dws;}@Bean("shiroFilterFactoryBean")publicShiroFilterFactoryBeanfactoryBean(){ShiroFilterFactoryBean sffb=newShiroFilterFactoryBean();//设置安全管理器
        sffb.setSecurityManager(securityManager());//设置需要登录但没有登录的地址
        sffb.setLoginUrl("");//检测到没有权限时的跳转地址
        sffb.setUnauthorizedUrl("");return sffb;}@BeanpublicMysqlRealmmysqlRealm(){MysqlRealm mysqlRealm=newMysqlRealm();//变动的地方: 配置加密管理器 登录时 会使用该加密方式对输入的密码进行加密,再和数据库的密码进行比对HashedCredentialsMatcher hsm =newHashedCredentialsMatcher();
        hsm.setHashAlgorithmName("sha-256");//加密方式 与注册时保持一致
        hsm.setHashIterations(100);//散列次数 与注册时保持一致
        mysqlRealm.setCredentialsMatcher(hsm);return mysqlRealm;}}

4 最终测试

4.1 当账户输入有误时
a 点击登录按钮前

在这里插入图片描述

b 点击登录按钮后

在这里插入图片描述

4.2 当账户被锁定时
a 点击登录按钮前

在这里插入图片描述

b 点击登录按钮后

在这里插入图片描述

4.3 当密码输入有误时(该用户并没有被锁定)
a 点击登录按钮前

在这里插入图片描述

b 点击登录按钮后

在这里插入图片描述

4.4 当账户密码输入均正确时
a 点击登录按钮前

在这里插入图片描述

b 点击登录按钮后

在这里插入图片描述


本文转载自: https://blog.csdn.net/SSS4362/article/details/128699093
版权归原作者 SSS4362 所有, 如有侵权,请联系我们删除。

“Spring Boot学习篇(十)”的评论:

还没有评论