目录

今天的知识是与上次所分享的知识相关联的,在Shiro入门的基础进行编写,上次之前的数据是死数据(放在Shiro.ini)而这次是活数据,可以连接到数据库,运用域Relam知识。同时出于维护用户的经济利益,保护数据的安全,我们会使用md5对密码进行加密

一、Shiro认证(ssm)

1.  导入pom依赖

2、在web容器配置文件中 配置过滤器

3、使用mybatis逆向生成工具生成我们所需要的表的model和mapper

4、在userMapper.xml中映射根据用户名查找的方法

5、在mapper与业务层中添加方法

6、自定义域 Myrealm继承域

7、配置spring与shiro的集成文件

二、密码加盐加密


今天的知识是与上次所分享的知识相关联的,在Shiro入门的基础进行编写,上次之前的数据是死数据(放在Shiro.ini)而这次是活数据,可以连接到数据库,运用域Relam知识。同时出于维护用户的经济利益,保护数据的安全,我们会使用md5对密码进行加密

一、Shiro认证(ssm)

目的:将死数据变为数据库中的数据

实现步骤:

1.  导入pom依赖

   <!--shiro依赖--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.3.2</version></dependency>

2、在web容器配置文件中 配置过滤器

过滤器的作用:拦截所有请求并交给Shiro进行处理

<!-- shiro过滤器定义 --><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --><param-name>targetFilterLifecycle</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

3、使用mybatis逆向生成工具生成我们所需要的表的model和mapper

  <table schema="" tableName="t_shiro_user" domainObjectName="User"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"></table><table schema="" tableName="t_shiro_role" domainObjectName="RoUserle"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"></table><table schema="" tableName="t_shiro_user_role" domainObjectName="Role"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"></table><table schema="" tableName="t_shiro_permission" domainObjectName="Permission"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"></table><table schema="" tableName="t_shiro_role_permission" domainObjectName="RoPermission"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"></table>

4、在userMapper.xml中映射根据用户名查找的方法

由于我们使用md5将密码加密后,我们用户在登陆时就不需要向以前一样拿到用户密码,而是使用用户名进行查找

 <select id="queryUserByUserName" resultType="com.zjy.model.User" parameterType="java.lang.String">select<include refid="Base_Column_List" />from t_shiro_userwhere userName = #{userName}</select>

5、在mapper与业务层中添加方法

mapper

 User queryUserByUserName(@Param("user") String userName);

userbiz

package com.zjy.biz;import com.zjy.model.User;
import org.apache.ibatis.annotations.Param;/*** @author zjy* @site Bi8boYin* @company xxx公司* @create  2022-08-25 13:55*/
public interface UserBiz {int updateByPrimaryKey(User record);int deleteByPrimaryKey(Integer userid);int insert(User record);int insertSelective(User record);User selectByPrimaryKey(Integer userid);User queryUserByUserName(@Param("user") String userName);int updateByPrimaryKeySelective(User record);
}

业务实现类:当我们将数据交给shiro时,spring的上下文还未加载完毕,所以需要我们将业务层添加进类注解中

package com.zjy.biz.impl;import com.zjy.biz.UserBiz;
import com.zjy.mapper.UserMapper;
import com.zjy.model.User;
import org.springframework.stereotype.Service;/*** @author zjy* @site Bi8boYin* @company xxx公司* @create  2022-08-25 14:00*/
@Service("UserBiz")
public class UserBizImpl implements UserBiz {private UserMapper userMapper;@Overridepublic int updateByPrimaryKey(User record) {return userMapper.updateByPrimaryKey(record);}@Overridepublic int deleteByPrimaryKey(Integer userid) {return userMapper.deleteByPrimaryKey(userid);}@Overridepublic int insert(User record) {return userMapper.insert(record);}@Overridepublic int insertSelective(User record) {return userMapper.insertSelective(record);}@Overridepublic User selectByPrimaryKey(Integer userid) {return userMapper.selectByPrimaryKey(userid);}@Overridepublic User queryUserByUserName(String userName) {return userMapper.queryUserByUserName(userName);}@Overridepublic int updateByPrimaryKeySelective(User record) {return userMapper.updateByPrimaryKeySelective(record);}
}

6、自定义域 Myrealm继承域

package com.zjy.shiro;import com.zjy.biz.UserBiz;
import com.zjy.model.User;
import sun.net.www.protocol.http.AuthenticationInfo;/*** @author zjy* @site Bi8boYin* @company xxx公司* @create  2022-08-25 14:12*/
public class MyRealm extends AuthorizingRealm {private UserBiz userBiz;public UserBiz getUserBiz() {return userBiz;}public void setUserBiz(UserBiz userBiz) {this.userBiz = userBiz;}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("身份认证...");String username = token.getPrincipal().toString();String password = token.getCredentials().toString();User user = userBiz.queryUserByUserName(username);
//        拿到数据库中的用户信息,放入token凭证中,用于controler进行对比AuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),ByteSource.Util.bytes(user.getSalt()),this.getName());return info;}
}

7、配置spring与shiro的集成文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置自定义的Realm--><bean id="shiroRealm" class="com.zjy.shiro.MyRealm"><property name="UserBiz" ref="UserBiz" /><!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 --><!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 --><!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 --><!--以下三个配置告诉shiro将如何对用户传来的明文密码进行加密--><property name="credentialsMatcher"><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!--指定hash算法为MD5--><property name="hashAlgorithmName" value="md5"/><!--指定散列次数为1024次--><property name="hashIterations" value="1024"/><!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储--><property name="storedCredentialsHexEncoded" value="true"/></bean></property></bean><!--注册安全管理器--><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="shiroRealm" /></bean><!--Shiro核心过滤器--><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- Shiro的核心安全接口,这个属性是必须的 --><property name="securityManager" ref="securityManager" /><!-- 身份验证失败,跳转到登录页面 --><property name="loginUrl" value="/login"/><!-- 身份验证成功,跳转到指定页面 --><!--<property name="successUrl" value="/index.jsp"/>--><!-- 权限验证失败,跳转到指定页面 --><property name="unauthorizedUrl" value="/unauthorized.jsp"/><!-- Shiro连接约束配置,即过滤链的定义 --><property name="filterChainDefinitions"><value><!--注:anon,authcBasic,auchc,user是认证过滤器perms,roles,ssl,rest,port是授权过滤器--><!--anon 表示匿名访问,不需要认证以及授权--><!--authc表示需要认证 没有进行身份认证是不能进行访问的--><!--roles[admin]表示角色认证,必须是拥有admin角色的用户才行-->/user/login=anon/user/updatePwd.jsp=authc/admin/*.jsp=roles[admin]/user/teacher.jsp=perms["user:update"]<!-- /css/**               = anon/images/**            = anon/js/**                = anon/                     = anon/user/logout          = logout/user/**              = anon/userInfo/**          = authc/dict/**              = authc/console/**           = roles[admin]/**                   = anon--></value></property></bean><!-- Shiro生命周期,保证实现了Shiro内部lifecycle函数的bean执行 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

8、编写登陆的控制层代码

package com.zjy.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req, HttpServletResponse resp){String username = req.getParameter("username");String password = req.getParameter("password");UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);Subject subject = SecurityUtils.getSubject();try {subject.login(usernamePasswordToken);req.getRequestDispatcher("main.jsp").forward(req, resp);} catch (Exception e) {req.setAttribute("message", "您的用户名密码输入有误!!!");try {req.getRequestDispatcher("login.jsp").forward(req, resp);} catch (ServletException e1) {e1.printStackTrace();} catch (IOException e1) {e1.printStackTrace();}}return null;}@RequestMapping("/logout")public String logout(HttpServletRequest req, HttpServletResponse resp){Subject subject = SecurityUtils.getSubject();subject.logout();try {resp.sendRedirect(req.getContextPath()+"/login.jsp");} catch (IOException e) {e.printStackTrace();}return null;}
}

二、密码加盐加密

盐加密工具类,在做新增用户的时候使用,将加密后的密码、及加密时候的盐放入数据库;

package com.zjy.util;import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;public class PasswordHelper {/*** 随机数生成器*/private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();/*** 指定hash算法为MD5*/private static final String hashAlgorithmName = "md5";/*** 指定散列次数为1024次,即加密1024次*/private static final int hashIterations = 1024;/*** true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储*/private static final boolean storedCredentialsHexEncoded = true;/*** 获得加密用的盐** @return*/public static String createSalt() {return randomNumberGenerator.nextBytes().toHex();}/*** 获得加密后的凭证** @param credentials 凭证(即密码)* @param salt        盐* @return*/public static String createCredentials(String credentials, String salt) {SimpleHash simpleHash = new SimpleHash(hashAlgorithmName, credentials,salt, hashIterations);return storedCredentialsHexEncoded ? simpleHash.toHex() : simpleHash.toBase64();}/*** 进行密码验证** @param credentials        未加密的密码* @param salt               盐* @param encryptCredentials 加密后的密码* @return*/public static boolean checkCredentials(String credentials, String salt, String encryptCredentials) {return encryptCredentials.equals(createCredentials(credentials, salt));}public static void main(String[] args) {//盐String salt = createSalt();System.out.println(salt);System.out.println(salt.length());//凭证+盐加密后得到的密码String credentials = createCredentials("123", salt);System.out.println(credentials);System.out.println(credentials.length());boolean b = checkCredentials("123", salt, credentials);System.out.println(b);}
}

测试结果:

盐加密的运行结果:

注意看两次密码都是一样的,但是最后加密出来的结果是不一样的:这就体现了Shiro框架的安全性高

接下来看看md5加密后的结果:

加密密码123456:

当我再次打开网站时,(注意时间)去加密这个密码时,加密结果还是一样的:

经过以上对比,md5的加密方式和Shiro的盐加密,shiro的盐加密安全性更高!

补充:

1、简介:MD5消息摘要算法,属Hash算法一类。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要(32位的数字字母混合码)。

2、MD5主要特点:不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样

3、MD5的性质:3.1、压缩性3.2、容易计算3.3、抗修改性3.4、弱抗碰撞3.5、强抗碰撞

Shiro认证及加盐加密相关推荐

  1. 【Shiro权限管理】10.Shiro为密码加盐

    上一篇我们提到了使用Shiro为密码进行MD5加密,这次来说一下密码加盐的问题. 当两个用户的密码相同时,单纯使用不加盐的MD5加密方式,会发现数据库中存在相同结构的密码, 这样也是不安全的.我们希望 ...

  2. Python项目-Day26-数据加密-hash加盐加密-token-jwt

    Python项目-Day26-数据加密-hash加盐加密-token-jwt 数据加密 import hashlibpwd='a123456' #sha1的参数必须是二进制 temp=hashlib. ...

  3. 【SpringSSM项目】搏击俱乐部 使用邮箱进行登录注册 密码加盐加密

    在注册页面使用邮箱进行注册,注册后发送带有确认码的邮件到邮箱中,通过邮件确认注册 编写数据库 登录注册需要使用到用户表 table userinfo 包含 账号状态 用户名 邮箱 密码 头像 过期时间 ...

  4. 基于java注册登录MD5算法加盐加密颁发 Token身份令牌使用各种邮箱发送验证码详解雪花算法

    目的作用 == 在项目中,为了防止别人窥视我们的密码通常我们会采取一些加密方式.这里简单介绍一下MD5 加盐加密方法,MD5叫做信息-摘要算法,严格来说不是加密方式,而是信息摘要. 对于可以接触到数据 ...

  5. MD5工具类 加盐加密 及编码

    titls: MD5工具类加密 date: 2018/11/12 10:03:42 categories: 开发module import java.security.MessageDigest; i ...

  6. md5加密,md5加盐加密和解密

    package com.java.test;import java.security.MessageDigest; import java.security.SecureRandom; import ...

  7. 密码MD5加盐加密----注册、校验、修改模块

    思路:     单纯的MD5加密容易被碰撞破解,考虑将密码加上一个随机字符串(盐),再一同进行MD5加密,提高安全性. 此时,盐相当于另一半秘钥,需将盐一同存入数据库,用以验证. 实现过程:      ...

  8. MD5加盐加密工具类(可直接使用)

    MD5加盐加密工具类 在我们做项目时,涉及到用户密码,而正常来说数据库中不会直接存储明文的密码,都是加密之后的密码. 密码加密的方式有很多,比如: ① 3DES.AES.DES:使用对称加密算法,可以 ...

  9. java md5加盐与解密_md5加密,md5加盐加密和解密

    packagecom.java.test;importjava.security.MessageDigest;importjava.security.SecureRandom;importjava.u ...

最新文章

  1. Oracle Spatial构建自定义投影坐标系
  2. Eclipse正确配置Tomcat之后仍然报错Type Target runtime Apache Tomcat v8.0 is not defined解决方式
  3. mysql按加号没反应_请各位大哥给小老弟解疑答惑一下 为什么点击加号没有反应?感谢...
  4. 鸿蒙不是安卓也不是Linux
  5. android Mediaplayer各种属性和方法简单介绍
  6. 001 - JavaScript Array String
  7. Java线程之CompletionService
  8. idea右边maven全爆红_通过Idea创建Spring Boot java项目
  9. access窗体主体居中
  10. 使用Word的VBA功能过滤敏感词,实现网络文章过审
  11. 中职计算机考证的软件
  12. stm32连接热敏打印机
  13. 12星座的出生年月日性格_十二星座的出生日期及对应性格
  14. pydub mp3转wav
  15. 解决戴尔电脑耳机插入后无效,外放正常的问题
  16. matlab if嵌套函数,MATLAB嵌套函数的应用
  17. IOS 16 UITabBarItem设置字体属性崩溃
  18. matlab取矩阵元素的模,Matlab矩阵元素提取
  19. 如何实现服务注册与发现?
  20. Python将图片转化成文字

热门文章

  1. HTML5 APP开发与原生态APP比较有什么好处?
  2. 三星gtn8010安卓7_三星GT-N8010刷机教程
  3. 淘宝运营 降低跳失率的方法 优化主图 优化详情页 优化评论
  4. python链表值讲解_python数据结构之链表详解
  5. Volatile的优缺点
  6. 转载:中国这10家慕课网站,您需要知道!
  7. 安卓毕业设计-图书馆管理系统-新手练手项目
  8. linux微信教程 百度云,2019-03-08 linux安装QQ,微信,百度云,迅雷
  9. 数据分析 - 跨境电商爬虫成长记 之 第一篇:python常用爬虫框架与工具
  10. Ubuntu命令之alias - 设置命令的别名