Spring Boot学习篇(十)

news2024/12/22 20:58:50

Spring Boot学习篇(十)

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

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

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

在这里插入图片描述

1.2 两种生成密文的方式

1.2.1 自己指定盐
a 核心代码
 public static String shaPassword(String oldPwd,String salt){
        return new SimpleHash("sha-256",oldPwd,salt,100).toString();
}
b 完整代码
package com.zlz.util;
import org.apache.shiro.crypto.hash.SimpleHash;
import java.util.Random;
public class SHAUtil01 {
    /**
     * 对密码使用sha256算法的方式加密
     * 加密不可逆: 无法通过新生成密文来反推出原来的密码
     * 盐是为了提高密码的安全系数的 随机生成的
     * 实际是拿你随机生成的盐和原来的字符串拼接在一起在来生成密文
     * 一般是可以使用随机字符串来表示盐的
     * hashIteration 表示加密计算的次数(拿盐和字符串拼接的次数) 散列次数越多 安全系越高
     * @param oldPwd 原密码
     * @param salt  盐
     * @return
     */
    public static String shaPassword(String oldPwd,String salt){
        return new SimpleHash("sha-256",oldPwd,salt,100).toString();
    }
    public static void main(String[] args) {
        //想要对admin这个密码进行加密.sha-256是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次
        //注意这个盐是建议每个账户一个,尽量不要重复
        String newPwd = SHAUtil01.shaPassword("admim", "q1");
        System.out.println(newPwd);
    }
}
1.2.2 随机生成盐
a 核心代码
//①定义一个随机生成10位含字母数字符号的盐
static Random random=new Random();
public static String getSalt(){
    //盐从以下这些字符中去随机取出10个出来,下面盐的字符串是可以自定义的,专门弄一个方法拿到盐
    String salts="ewsfjbwdufgsfsnuivhe123456789/*;[]";
    StringBuffer salt=new StringBuffer();
    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的加密方式(不可逆的)进行加密得到密文
public static String shaPassword(String oldPwd){
    return new SimpleHash("sha-256",oldPwd,getsalt(),100).toString();
}
b 完整代码
package com.zlz.util;

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

import java.util.Random;

public class SHAUtil02 {
    /**
     * 对密码使用sha-256算法的方式加密
     * 加密不可逆: 无法通过新生成密文来反推出原来的密码
     *
     * 盐是为了提高密码的安全系数的 随机生成的
     * 实际是拿你随机生成的盐和原来的字符串拼接在一起在来生成密文
     * 一般是可以使用随机字符串来表示盐的
     * hashIteration 表示加密计算的次数(拿盐和字符串拼接的次数) 散列次数越多 安全系越高
     * @param oldPwd 原密码
     * @return 字符串形式的密文
     */
    public static String shaPassword(String oldPwd){
        return new SimpleHash("sha-256",oldPwd,getSalt(),100).toString();
    }
    static Random random=new Random();
    public static String getSalt(){
        //盐从以下这些字符中去随机取出10个出来,下面盐的字符串是可以自定义的,专门弄一个方法拿到盐
        String salts="ewsfjbwdufgsfsnuivhe123456789/*;[]";
        StringBuffer salt=new StringBuffer();
        for (int i = 1; i <=10; i++) {
            //charAt是取出索引处的字符
            char c=salts.charAt(random.nextInt(salts.length()));
            salt.append(String.valueOf(c));
        }
        return salt.toString();
    }
    public static void main(String[] args) {
        //想要对admin这个密码进行加密.sha-256是不可逆的加密方式,对同一个密码生成的密文是唯一的,无论你执行多少次
        String newPwd = SHAUtil02.shaPassword("admin");
        System.out.println(newPwd);
    }
}

1.3 手动变更数据表(以自己指定盐的方式)

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

在这里插入图片描述

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

在这里插入图片描述

1.3.3 账户"bbb"所对应的密文
a 测试代码
public static void main(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
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` int NOT NULL,
  `username` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `password` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `salt` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `suo` int NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = COMPACT;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'admin', '7e84f2fbdc9de493dc1e17c44b163ebc9168bc472f26db231f472f1012e62d87', 'q1', 0);
INSERT INTO `sys_user` VALUES (2, 'aaa', '18ae76b69e6b7b2ae78100013442beafb692bbbad663b1ff5845f0036b446ad7', 'q2', 0);
INSERT INTO `sys_user` VALUES (3, 'bbb', '7c8425aa02dfdfc973257f3b2a4ded786eadee830d7a29a900669727fa7a5966', 'q3', 1);

SET FOREIGN_KEY_CHECKS = 1;

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

package com.zlz.config;

import com.zlz.entity.SysUser;
import com.zlz.mapper.SysUserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

public class MysqlRealm extends AuthorizingRealm {
    //授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        return null;
    }
    @Autowired
    SysUserMapper sysUserMapper;
    //认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
        //①在认证方法里面获取输入的用户名
        String username = (String) at.getPrincipal();
        SysUser user = sysUserMapper.findUserByUsername(username);
        if (user == null) {
            //②如果账户不存在,就抛出账户不存在异常
            throw new UnknownAccountException();
        }
        //③检查账户是否锁定 如果锁定的话,那就会抛出锁定异常
        if(user.getSuo()==1){
            throw new LockedAccountException();
        }
        //密码错误,shiro会自动帮你抛出密码错误这个异常的
//        System.out.println("实例对象名称:");
        //④拿到盐(放在第三个形参的位置)-----变动的地方
        ByteSource salt = ByteSource.Util.bytes(user.getSalt());
        //⑤把对应的参数设置进去
        SimpleAuthenticationInfo s=new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),salt,getName());
        return s;
    }
}

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

package com.zlz.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConig {
    //安全管理器的配置
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager dws=new DefaultWebSecurityManager();
        dws.setRealm(mysqlRealm());
        //设置会话管理器,保证第一次访问的时候不会出错
        dws.setSessionManager(new DefaultWebSessionManager());
        return dws;
    }
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean factoryBean(){
        ShiroFilterFactoryBean sffb=new ShiroFilterFactoryBean();
        //设置安全管理器
        sffb.setSecurityManager(securityManager());
        //设置需要登录但没有登录的地址
        sffb.setLoginUrl("");
        //检测到没有权限时的跳转地址
        sffb.setUnauthorizedUrl("");
        return sffb;
    }
    @Bean
    public MysqlRealm mysqlRealm(){
        MysqlRealm mysqlRealm=new MysqlRealm();
        //变动的地方: 配置加密管理器 登录时 会使用该加密方式对输入的密码进行加密,再和数据库的密码进行比对
        HashedCredentialsMatcher hsm = new HashedCredentialsMatcher();
        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 点击登录按钮后

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/165678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一篇文章彻底搞懂折半查找法[二分查找法]算法~

算法实现的要求&#xff1a; 折半查找法又称为二分查找法&#xff0c;这种方法对待查找的列表有两个要求&#xff1a; 1&#xff1a;必须采用顺序存储结构 2&#xff1a;必须按关键字大小有序排列算法思想&#xff1a; 将表中间位置记录的关键字与查找关键字进行比较&#x…

性能测试时那些「难以启齿」的问题-CPU相关

NO.1 为什么cpu使用率可以>100%? 小白的我在进行压测的时候&#xff0c;查看服务的cpu总使用率如下&#xff0c;总使用率会超过100%&#xff0c;这个数据是怎么来的呢&#xff0c;为什么会有大于100%的情况呢&#xff1f; 作为小白的我刚开始觉得这个问题应该很基础&#x…

Go语言实现猜数字小游戏

目录 前言 一、设计思路 二、代码编写 2.1 产生随机数 2.2 用户输入数据 2.3 核心代码 三、 全部代码 四、效果图 总结 前言 最近在学习go语言&#xff0c;刚刚学完go语言的基础语法。编写了一个猜数字的小游戏来练习循环、分支语句、变量定义、输入输出等基础的go语…

4、变量与常量

目录 一、标识符和关键字 1.标识符 2.关键字 二、声明变量 三、声明常量 四、变量的有效范围 1. 成员变量 2. 局部变量 一、标识符和关键字 1.标识符 Java语言规定标识符由任意顺序的字母、下画线&#xff08;_&#xff09;、美元符号&#xff08;$&#xff09;和数字…

【数据结构】手撕八大排序算法

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1.排序的概念&#xff1a; 2.八大排序的思路及其细节 2.1直接插入排序 …

适合编程初学者的开源项目:小游戏2048(安卓Compose版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

SpringMVC面试题

概述 什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f; Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架&#xff0c;通过把模型-视图-控制器分离&#xff0c;将web层进行职责解耦&#xff0c;把复杂的web应用分成逻辑清…

如何在Linux上搭建C++开发环境

工欲善其事&#xff0c;必先利其器&#xff01;我们要在Linux上开发C程序&#xff0c;就要先搭建好它的开发环境。 搭建环境步骤安装Linux安装开发工具写一个demo在项目根目录创建一个构建脚本build.sh使用CodeLite IDE打开项目安装Linux Linux的发行版本很多&#xff0c;萝卜…

测试开发——测试分类

目录 一、 有关测试用例的回顾 二、 测试用例的划分 1、 按照测试对象来划分 可靠性测试 容错性测试 内存泄漏测试 弱网测试 2、按照是否查看代码划分 3、按照开发阶段划分 一、 有关测试用例的回顾 万能测试用例设计公式 如何根据需求去设计测试用例&#xff1f; …

计算机视觉OpenCv学习系列:第三部分、滚动条操作

第三部分、滚动条操作第一节、滚动条操作1.事件响应函数&#xff08;1&#xff09;UI组件时间响应过程&#xff08;2&#xff09;事件响应函数&#xff08;3&#xff09;创建窗口函数&#xff08;4&#xff09;调整图像亮度2.滚动条操作3.代码练习与测试学习参考第一节、滚动条…

Python 协程学习有点难度?这篇文字值得你去收藏

Python 协程在基础学习阶段&#xff0c;属于有难度的知识点&#xff0c;建议大家在学习的时候&#xff0c;一定要反复练习。 Python 中的协程是一种用户态的轻量级线程。它与普通的线程不同&#xff0c;普通线程是由操作系统调度的&#xff0c;而协程是由程序自己调度的。因此&…

【ESP 保姆级教程】玩转emqx篇③ ——认证安全之使用内置数据库(Mnesia)的密码认证

忘记过去&#xff0c;超越自己 ❤️ 博客主页 单片机菜鸟哥&#xff0c;一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-01-15 ❤️❤️ 本篇更新记录 2022-01-15 ❤️&#x1f389; 欢迎关注 &#x1f50e;点赞 &#x1f44d;收藏 ⭐️留言&#x1f4dd;&#x1f64…

Transformer模型详解相关了解

文章目录Transformer模型详解1.前言1.1 Transformer 整体结构1.2 Transformer 的工作流程2. Transformer 的输入2.1 单词 Embedding2.2 位置 Embedding3. Self-Attention&#xff08;自注意力机制&#xff09;3.1 Self-Attention 结构3.2 Q, K, V 的计算3.3 Self-Attention 的输…

《神经网络与深度学习》 邱希鹏 学习笔记(一)

一、机器学习的基本要素 机器学习的基本要素: 模型 学习准则 优化算法 其中模型分为线性和非线性。学习准则有用损失函数来评价模型的好坏&#xff0c;还有经验风险最小化准则&#xff0c;大概意思就是在平均损失函数中获得最小的损失函数&#xff0c;但是因为样本可能很小&…

Goodbye 2022,Welcome 2023 | 锁定 2023

引言又是一年春来到&#xff0c;新年应比旧年好。旧岁已辞&#xff0c;新年已到&#xff0c;新旧更迭之际&#xff0c;真想剪个头发换身行头&#xff0c;就能重新出发。但终究是要回头看看啊&#xff0c;那一路而来的荆棘与芬芳&#xff0c;才是成长的印记啊。那就回拨记忆&…

和涤生大数据的故事

1自我介绍 大家好&#xff0c;我是泰罗奥特曼&#xff0c;毕业于东北的一所不知名一本大学&#xff0c;学校在一个小城市里面&#xff0c;最热闹的地方是一个四层楼的商城&#xff0c;专业是信息管理与信息系统&#xff0c;由于是调剂的&#xff0c;所以我也不知道这个专业是干…

一篇文章带你学完JavaScript基础知识,超全的JavaScript知识点总结

目录 内置函数 alert警告框 promopt提示框 console控制台 字面量 数字型 字符串型 变量 声明与赋值 类型检测 类型转换 比较运算符 逻辑运算符 条件句 if else switch break,continue while 赋值运算符 函数 关键字形式函数 变量认知 作用域 表达式…

什么样的故障让阿里云换了总裁?

&#x1f4e3;&#x1f4e3;&#x1f4e3;&#x1f4e3;&#x1f4e3;&#x1f4e3;&#x1f4e3; &#x1f38d;大家好&#xff0c;我是慕枫 &#x1f38d;前阿里巴巴高级工程师&#xff0c;InfoQ签约作者、阿里云专家博主&#xff0c;一直致力于用大白话讲解技术知识 &#x…

SpringBoot数据访问Redis

目录 前言 1、Redis自动配置 2、RedisTemplate与Lettuce 3、切换至jedis 前言 Redis 是一个开源&#xff08;BSD许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构&#xff0c;如 字符串…

基于贝叶斯算法的邮件过滤管理系统的设计和实现(Vue+SpringBoot)

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…