本例为在idea下shiro集成springMVC。仅有一个认证加密方式(一个realm

为什么是MD5盐值加密呢?shiro用密码匹配,密码一样,就ok。如果两个用户的密码一样,则就会造成麻烦。所以使用MD5盐值加密。盐值加密简单来说就是:两个一样的西红柿,加不同的盐炒出来的味道不一样。什么适合作为盐值呢?肯定是惟一的东西。

比如用户名(一般采用手机号,或者邮箱等等)(用户id也ok)。下面来详细说明。

1.idea中新建立spring-springMVC项目。(建立方法可以参考之前的文章)

2.需要导入shiro的jar包。shiro的所有的包可以去http:shiro.apache.org网站下载。里面也有一些实例项目可以参考。

这里需要这么四个包:

在idea中的lib中导入这些包,注意一定要右键add as library和在program structure中put into。关于如何导入,可以参考我之前的文章。

3.配置ss的文件。

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--1.配置shiroFilter--><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><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>
</web-app>

dispatcher-servler.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置controller扫描--><context:component-scan base-package="com.atguigu.shiro"/><mvc:annotation-driven/><mvc:default-servlet-handler/><!--配置视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/"/><property name="suffix" value=".jsp"/></bean></beans>

applicationContext.xml:

<?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"><!-- =========================================================Shiro Core Components - Not Spring Specific========================================================= --><!-- Shiro's main business-tier object for web-enabled applications(use DefaultSecurityManager instead when there is no web environment)--><!--1. 配置 SecurityManager!--><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="cacheManager" ref="cacheManager"/><!--仅仅有一个realm就使用下面这个--><property name="realm" ref="jdbcRealm"></property></bean><!-- Let's use some enterprise caching support for better performance.  You can replace this with any enterprisecaching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc --><!--2. 配置 CacheManager.2.1 需要加入 ehcache 的 jar 包及配置文件.--><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><!-- Set a net.sf.ehcache.CacheManager instance here if you already have one.  If not, a new onewill be creaed with a default config:<property name="cacheManager" ref="ehCacheManager"/> --><!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you wanta specific Ehcache configuration to be used, specify that here.  If you don't, a defaultwill be used.: --><property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/></bean><!-- Used by the SecurityManager to access security data (users, roles, etc).Many other realm implementations can be used too (PropertiesRealm,LdapRealm, etc. --><!--3. 配置 Realm3.1 直接配置实现了 org.apache.shiro.realm.Realm 接口的 bean--><bean id="jdbcRealm" class="com.atguigu.shiro.realms.ShiroRealm"><property name="credentialsMatcher"><bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><property name="hashAlgorithmName" value="MD5"></property><property name="hashIterations" value="1024"></property></bean></property></bean><!-- =========================================================Shiro Spring-specific integration========================================================= --><!-- Post processor that automatically invokes init() and destroy() methodsfor Spring-configured Shiro objects so you don't have to1) specify an init-method and destroy-method attributes for every beandefinition and2) even know which Shiro objects require these methods to becalled. --><!--4. 配置 LifecycleBeanPostProcessor. 可以自定的来调用配置在 Spring IOC 容器中 shiro bean 的生命周期方法.--><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/><!-- Enable Shiro Annotations for Spring-configured beans.  Only run afterthe lifecycleBeanProcessor has run: --><!--5. 启用 IOC 容器中使用 shiro 的注解. 但必须在配置了 LifecycleBeanPostProcessor 之后才可以使用.--><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"/><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/></bean><!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -web.xml uses the DelegatingFilterProxy to access this bean.  This allows usto wire things with more control as well utilize nice Spring things such asPropertiesPlaceholderConfigurer and abstract beans or anything else we might need: --><!--6. 配置 ShiroFilter.6.1 id 必须和 web.xml 文件中配置的 DelegatingFilterProxy 的 <filter-name> 一致.若不一致, 则会抛出: NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.--><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"/><property name="loginUrl" value="/login.jsp"/><property name="successUrl" value="/list.jsp"/><property name="unauthorizedUrl" value="/unauthorized.jsp"/><!--配置哪些页面需要受保护.以及访问这些页面需要的权限.1). anon 可以被匿名访问2). authc 必须认证(即登录)后才可能访问的页面.3). logout 登出.4). roles 角色过滤器--><property name="filterChainDefinitions"><value>/login.jsp = anon/shiro/login = anon/shiro/logout = logout# everything else requires authentication:/** = authc</value></property></bean></beans>

web 目录下的文件:

建立realm:

package com.atguigu.shiro.realms;import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.ByteSource;public class ShiroRealm extends AuthenticatingRealm {@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("[FirstRealm]+doGetAuthenticationInfo");//1.把AuthenticationToken对象装换为UsernamePasswordTokenUsernamePasswordToken upToken= (UsernamePasswordToken) token;//2.从UsernamePasswordToken中来获取usernameString username = upToken.getUsername();//3.调用数据库的方法,从数据库中查询username对应的记录System.out.println("从数据库中获取username:"+username+"所对应的信息");//4.若用户不存在,则可以抛出UnKnownAccountException异常if("unknown".equals(username)){throw new UnknownAccountException("用户不存在!");}//5.根据用户信息的情况,决定是否需要抛出其他的AuthenticationException异常if("monster".equals(username)){throw new LockedAccountException("用户被锁定!");}//6.根据用户的情况,来构建AuthenticationInfo对象并且返回//通常使用的实现类是SimpleAuthenticationInfo//以下信息从数据库中获取//<1.principal:认证的实体信息,可以是username也可以是数据表对应的实体类对象Object principal=username;//<2.credentials:密码Object credentials=null;if("admin".equals(username)){credentials="038bdaf98f2037b31f1e75b5b4c9b26e";}else if("user".equals(username)){credentials="098d2c478e9c11555ce2823231e02ec1";}//<3.realName:当前realm对象的name,调用父类对象的getName()方法即可String realmName=getName();//<4 盐值 这个盐值要唯一,我们假设这里用户名是唯一的,我们使用用户名作为盐值//盐值的作用:如果两个人的密码一样的话,就要盐值,就像西红柿,家不同的盐味道不一样!ByteSource credentialsSalt=ByteSource.Util.bytes(username);SimpleAuthenticationInfo info=null;info=new SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName);return info;}public static void main(String[] args) {String algorithmName="MD5";Object credentials="123456";Object salt=ByteSource.Util.bytes("user");int hashIterations=1024;Object result = new SimpleHash(algorithmName, credentials, salt, hashIterations);System.out.println(result);}
}

注意,实际项目中,这个credentials是从数据库中拿到的。不是用下面的main方法现成加密的哈!

编写controller:

package com.atguigu.shiro.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@Controller
@RequestMapping("/shiro")
public class ShiroHandler {@RequestMapping(value = "/login",method = RequestMethod.POST)public String login(String username,String password){// 获取当前的 Subject. 调用 SecurityUtils.getSubject();Subject currentUser = SecurityUtils.getSubject();// let's login the current user so we can check against roles and permissions:// 测试当前的用户是否已经被认证. 即是否已经登录.// 调动 Subject 的 isAuthenticated()if (!currentUser.isAuthenticated()) {// 把用户名和密码封装为 UsernamePasswordToken 对象UsernamePasswordToken token = new UsernamePasswordToken(username, password);// remembermetoken.setRememberMe(true);try {// 执行登录.//这个token其实就传到了shiroRealm里面的那个tokencurrentUser.login(token);}// 所有认证时异常的父类.catch (AuthenticationException ae) {//unexpected condition?  error?System.out.println("登录失败:"+ae.getMessage());}}return "redirect:/list.jsp";}
}

注意这里一定要写上method。

login.jsp的内容:

<%--Created by IntelliJ IDEA.User: lenovoDate: 2019/8/30Time: 11:27To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/";
%>
<html>
<head><title>login</title>
</head>
<body>
<h4>login page</h4>
<form action="<%=basePath%>shiro/login" method="post">username:<input type="text" name="username"><br><br>password:<input type="password" name="password"><br><br><input type="submit">
</form>
</body>
</html>

需要登出:

在list.jsp中登出:

<%--Created by IntelliJ IDEA.User: lenovoDate: 2019/8/30Time: 11:27To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/";
%>
<html>
<head><title>list</title>
</head>
<body>
<h4>List Page</h4>
<a href="<%=basePath%>shiro/logout">Log Out</a>
</body>
</html>

完整的代码:

https://hn.devcloud.huaweicloud.com/codehub/project/db863c4dd09b44e1949853aa22197df3/codehub/7168568/home

流程:

ehcache.xml的内容:

<ehcache><!-- Sets the path to the directory where cache .data files are created.If the path is a Java System Property it is replaced byits value in the running VM.The following properties are translated:user.home - User's home directoryuser.dir - User's current working directoryjava.io.tmpdir - Default temp file path --><diskStore path="java.io.tmpdir"/><cache name="authorizationCache"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="0"overflowToDisk="false"statistics="true"></cache><cache name="authenticationCache"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="0"overflowToDisk="false"statistics="true"></cache><cache name="shiro-activeSessionCache"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="0"overflowToDisk="false"statistics="true"></cache><!--Default Cache configuration. These will applied to caches programmatically created throughthe CacheManager.The following attributes are required for defaultCache:maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/><!--Predefined caches.  Add your cache configuration settings here.If you do not have a configuration for your cache a WARNING will be issued when theCacheManager startsThe following attributes are required for defaultCache:name              - Sets the name of the cache. This is used to identify the cache. It must be unique.maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><!-- Sample cache named sampleCache1This cache contains a maximum in memory of 10000 elements, and will expirean element if it is idle for more than 5 minutes and lives for more than10 minutes.If there are more than 10000 elements it will overflow to thedisk cache, which in this configuration will go to wherever java.io.tmp isdefined on your system. On a standard Linux system this will be /tmp"--><cache name="sampleCache1"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="true"/><!-- Sample cache named sampleCache2This cache contains 1000 elements. Elements will always be held in memory.They are not expired. --><cache name="sampleCache2"maxElementsInMemory="1000"eternal="true"timeToIdleSeconds="0"timeToLiveSeconds="0"overflowToDisk="false"/> --><!-- Place configuration for your caches following --></ehcache>

shiro—MD5盐值加密相关推荐

  1. Springboot + Shiro——MD5 盐值加密(配置)

    其实这里所说的盐,简单的说,就是一组安全随机数.它会在特定的时候,加入到密码中(一般来说是加密后的密码).从而使密码变得更有味道(从单一简单化到复杂化),更安全. 如何做到? 1). 在 doGetA ...

  2. java shiro盐值加密_java中spring-shiro实现密码的MD5盐值加密

    看了网上很多教程,都提到有配置spring shiro的密码加密方式,甚至给出了自定义的Class来实现.却很少有通过配置来解决的. 密码的盐值加密方式应该是非常通用的,也可以算是基础吧.按理说spr ...

  3. Shiro(三) 身份认证源码分析与 MD5 盐值加密

    文章目录 1. 身份认证 2. 身份验证的基本流程 3. 身份验证实现 3.1 在 `login.jsp` 添加登录表单 3.2 添加表单提交的 Controller 3.3 完善 Realm 的身份 ...

  4. Spring Boot 整合 shiro 之盐值加密认证详解(六)

    Spring Boot 整合 shiro 之盐值加密认证详解 概述 不加盐认证 加入密码认证核心代码 修改 CustomRealm 新增获取密文的方法 修改 doGetAuthenticationIn ...

  5. shiro配置盐值加密

    shiro配置盐值加密 一:在shiro配置文件ShiroConfig.java中配置密码凭证匹配器 /*** 密码凭证匹配器,作为自定义认证的基础* @return*/@Beanpublic Has ...

  6. Spring-Security之加密操作(MD5,盐值加密)

    MD5加密算法 此处借用的是JDK内部的加密算法 public class MyPasswordEncoder implements PasswordEncoder {@Overridepublic ...

  7. Springboot-14 shiro整合mybati 密码可以用md5盐值加密 更加安全 授权认证登录

    导入pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  8. 登录操作之MD5盐值加密

    在商业项目中,登录操作往往需要对密码进行加密处理,以提高账号的安全程度,实现思路如下(来自于网络): 用户注册(或修改密码)时: 1)用户提供密码(以及其他用户信息): 2)系统为用户随机生成一个Sa ...

  9. java的md5盐值加密_MD5盐值加密

    import java.security.MessageDigest; import java.util.Random; import org.apache.commons.codec.binary. ...

最新文章

  1. 2.innodb后台线程
  2. 犹豫了许久,还是写个年总结记录一下吧
  3. java get方法报空指针_面试的哪些事儿之JAVA程序员面试笔试题(一)
  4. 计算机图形设计论文 真实图形生成技术的发展,绘制技术论文,关于计算机图形图像绘制技术的现状应用相关参考文献资料-免费论文范文...
  5. canvas绘制精细走动时钟
  6. EJB3.0学习笔记---JMS/MDB/Pub/Sub/P2P
  7. centos7 cuda测试_CentOS 7 安装cuda环境
  8. 《指针的编程艺术(第二版)》一3.10 程序实战
  9. $.type 怎么精确判断对象类型的 --(源码学习2)
  10. python3爬虫必学Xpath,快速使用lxml.etree
  11. MZD Studios|感谢你们,我挺过来了,不做老外舔狗 -Jerome Alan Chan
  12. iis 域名无法访问
  13. linux支持vmfs文件系统吗,调整vmfs文件系统块大小
  14. HTTP和MQTT协议实践
  15. linux之if语句详解
  16. JS正则——将字符串中的逗号替换成空格
  17. 电脑突然断电蓝屏导致Git错误的一种解决办法
  18. git 基本命令总结
  19. 凌动上网本改装linux,Ubuntu Netbook Remix 专为上网本打造的linux系统--梦飞翔的地方(梦翔天空)...
  20. ubuntu18 安装jdk后报错Error occu‘r‘re‘d during initialization of VM

热门文章

  1. android 动态向Gallery中添加图片及倒影3D效果
  2. 【RDP】win10家庭版 RDP wrapper 出现 not listening not supported
  3. 光影mod_效果不俗!《雷神之锤2》贴图/光影重制MOD新截图公布
  4. 16位异或 c语言,C语言位运算符:与、或、异或、取反、左移和右移
  5. 理解Go的Context机制
  6. java、js 对于四舍五入、向上取整、向下取整
  7. ubuntu 设置默认终端
  8. js json数组按某一字段排序
  9. tensorflow elu函数应用
  10. 06.计算机高级语言