shiro教程二:spingboot整合shiro实现认证权限的管理。包括密码MD5+salt加密。以及缓存的设置。
在shiro教程一中,我们已经知道了shiro框架的定义及简单上手,接下来我们就进入实战吧!
传送门:shiro教程一
关注公众号,文章会在公众号同步更新,谢谢大家关注!
首先附上项目的地址,欢迎大家下载和指导:github项目地址
数据库表文件,在mapper文件夹下面哦!
1.数据库表的设计
首先是数据库的设计,该项目使用的是mysql8.0 ,用户的信息、用户的角色信息(你是管理员还是普通用户)、用户的权限信息(你具有哪些操作(增删改查或者其他功能。) ,那么问题来了, 数据库的表怎么设计呢 ? 很简单哒。先附图后说明:
我们设计了5张表,用户信息表,角色信息表,权限信息表、用户角色表、角色权限表。 首先是用户信息表,用户的注册登录信息从这里存储/取出。当用户要查你是哪个角色时。就根据用户角色表来;用户要查你有哪些权限时,就根据角色权限表来。
/*
MySQL Data Transfer
Source Host: localhost
Source Database: shiro
Target Host: localhost
Target Database: shiro
Date: 2021/1/16 11:23:32
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_pers
-- ----------------------------
DROP TABLE IF EXISTS `t_pers`;
CREATE TABLE `t_pers` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(60) NOT NULL,
`url` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`salt` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_user_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_user_perms`;
CREATE TABLE `t_user_perms` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`roleid` int(10) NOT NULL,
`permsid` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`userid` int(10) NOT NULL,
`roleid` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', 'tom', '4980f486221eff4c6935d24bf41ccb96', 'bE!a4C!V');
INSERT INTO `t_user` VALUES ('2', 'lsg', 'a9286ead5cd36cfccbe0a56c10765ace', 'QFlNQ!7^');
2.代码上手
2.1 、项目结构图:
创建一个springboot应用。然后右击main,创建一个webapp文件夹。这里面放我们的页面。
(小提示:快速创建jsp页面:在创建的jsp空页面,中输入感叹号,然后按tab)
2.2、pom.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1 </version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.znzz</groupId>
<artifactId>springboot_jsp_shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_jsp_shiro</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 加入shiro和ehcachae缓存-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.3</version>
</dependency>
<!-- redis整合springboot,将缓存存入redis中-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--引入shiro整合的依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<!--引入jsp解析的依赖-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.3、实体类 (entity中三个实体类。)
2.3.1、User.java(用户信息)
package com.znzz.springboot_jsp_shiro.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String username;
private String password;
private String salt;
//定义一个角色集合
private List<Role> roles;
}
2.3.2、Role.java(角色信息)
package com.znzz.springboot_jsp_shiro.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
private String id;
private String name;
//定义一个权限的集合,因为权限时跟角色绑定的
private List<Perms> perms;
}
2.3.3、Perms.java(权限信息表)
package com.znzz.springboot_jsp_shiro.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Perms {
private String id;
private String name;
private String url;
}
2.4、Dao层,(接口,提供方法。)
UserMapper.java
package com.znzz.springboot_jsp_shiro.mapper;
import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
void save(User user);
User findByUserName(String username);
//根据用户名查询角色
User findRolesByUserName(String username);
//根据角色的id获取到权限集合
List<Perms> findPermsByRoleId(String id);
}
2.5、UserMapper.xml文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.znzz.springboot_jsp_shiro.mapper.UserMapper">
<insert id="save" parameterType="User" keyProperty="id" useGeneratedKeys="true" >
insert into t_user values (#{id},#{username},#{password},#{salt})
</insert>
<select id="findByUserName" parameterType="String" resultType="User">
select username,password,salt from t_user where username = #{username}
</select>
<resultMap id="userMap" type="User">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<!--角色信息 -->
<collection property="roles" javaType="list" ofType="Role">
<id column="id" property="id" />
<result column="rname" property="name"/>
</collection>
</resultMap>
<select id="findRolesByUserName" parameterType="String" resultMap="userMap">
select u.id uid, u.username,r.id,r.NAME rname
from t_user u
LEFT JOIN t_user_role ur
on u.id=ur.userid
LEFT JOIN t_role r
on ur.roleid=r.id
WHERE u.username=#{username}
</select>
<select id="findPermsByRoleId" parameterType="String" resultType="Perms">
select p.id , p.name , p.url , r.name from t_role r
left join t_role_perms rp
on r.id = rp.roleid
left join t_perms p
on rp.permsid = p.id
where r.id = #{id}
</select>
</mapper>
2.6、 application.properties 配置mysql连接,以及映射文件位置。
application.properties
server.servlet.context-path=/shiro
spring.application.name=shiro
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&userUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
mybatis.type-aliases-package=com.znzz.springboot_jsp_shiro.entity
mybatis.mapper-locations=classpath:mapper/*.xml
logging.level.com.znzz.springboot_jsp_shiro.mapper=debug
2.7、业务层。
2.7.1、UserService.java
package com.znzz.springboot_jsp_shiro.service;
import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import java.util.List;
public interface UserService {
void register(User user);
User findByUserName(String username);
//根据用户名查询角色
User findRolesByUserName(String username);
//根据角色的id获取到权限信息
List<Perms> findPermsByRoleId(String id);
}
2.7.2、UserServiceImpl.java
package com.znzz.springboot_jsp_shiro.service;
import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.mapper.UserMapper;
import com.znzz.springboot_jsp_shiro.utils.SaltUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
@Override
public void register(User user) {
//处理业务
//铭文的密码进行md5+ salt+ hash加密。
//1.生成随机salt
String salt = SaltUtils.getSalt(8) ;
user.setSalt(salt);
Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);
user.setPassword(md5Hash.toHex());
userMapper.save(user);
}
@Override
public User findByUserName(String username) {
return userMapper.findByUserName(username);
}
//根据用户名查询角色
@Override
public User findRolesByUserName(String username) {
return userMapper.findRolesByUserName(username);
}
//根据角色的id获取权限
@Override
public List<Perms> findPermsByRoleId(String id) {
return userMapper.findPermsByRoleId(id);
}
}
2.8、Controller层。
UserController.java
package com.znzz.springboot_jsp_shiro.controller;
import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 用来处理身份认证
* @param username
* @param password
* @return
*/
@PostMapping("/login")
public String login(String username, String password,Model model){
//获取主体对象
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username,password));
return "redirect:/index.jsp";
}catch (UnknownAccountException e){
e.printStackTrace();
System.out.println("用户名错误");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
} catch (Exception e){
e.printStackTrace();
System.out.println("请输入完整信息");
}
return "redirect:/login.jsp";
}
/**
* 退出登录
*
*/
@RequestMapping("logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login.jsp";
}
/**
* 用户注册校验
*/
@RequestMapping("/register")
public String register(User user){
try {
userService.register(user);
return "redirect:/login.jsp";
}catch (Exception e){
e.printStackTrace();
return "redirect:/register.jsp";
}
}
}
2.9.页面。
2.9.1、index.jsp(主页,登录成功之后的页面)
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>系统</title>
</head>
<body>
asdf
<ul>
<li><a href="">增</a>
<ul>
<shiro:hasPermission name="user:add:*">
<li><a href="">增加一个</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="user:update:*">
<li><a href="">增加2个</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="user:select:*">
<li><a href="">增加3个</a></li>
</shiro:hasPermission>
</ul>
</li>
<shiro:hasRole name="admin">
<li><a href="">珊</a></li>
<li><a href="">改</a></li>
<li><a href="">查</a></li>
</shiro:hasRole>
</ul>
<br />
<br />
<br />
<br />
<hr />
<a href="${pageContext.request.contextPath}/user/logout">退出</a>
</body>
</html>
2.9.2、login.jsp(登录页面)
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>登录</title>
</head>
<body>
登录界面
<p style="color: red">${msg}</p>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名: <input type="text" name="username"> <br />
密码: <input type="text" name="password"> <br />
验证码: <input type="text"> <img src=""alt="" /> <br />
<input type="submit" value="提交">
</form>
</body>
</html>
2.9.3、register.jsp(注册页面)
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>注册</title>
</head>
<body>
注册界面
<form action="${pageContext.request.contextPath}/user/register" method="post">
用户名: <input type="text" name="username"> <br />
密码: <input type="text" name="password"> <br />
<input type="submit" value="注册">
</form>
</body>
</html>
3.0、有关Realm的配置。
CustomerRealm.java
package com.znzz.springboot_jsp_shiro.shiro;
import com.znzz.springboot_jsp_shiro.entity.Perms;
import com.znzz.springboot_jsp_shiro.entity.Role;
import com.znzz.springboot_jsp_shiro.entity.User;
import com.znzz.springboot_jsp_shiro.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
//自定义的realm的类
//用来进行数据校验
public class CustomerRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取身份信息
String primaryPrincipal =(String) principals.getPrimaryPrincipal();
System.out.println("调用授权验证"+primaryPrincipal);
//根据身份信息获取角色信息
User user = userService.findRolesByUserName(primaryPrincipal);
System.out.println(userService.findRolesByUserName(primaryPrincipal));
//角色不为空,构建角色信息
//授权角色信息
if(!CollectionUtils.isEmpty(user.getRoles())){
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
user.getRoles().forEach(role -> {
simpleAuthorizationInfo.addRole(role.getName());
System.out.println("=========");
System.out.println("用户的角色:"+role.getName());
//角色遍历出来了,现在还需要权限。
List<Perms> perms = userService.findPermsByRoleId(role.getId());
if(!CollectionUtils.isEmpty(perms)){
perms.forEach(perm -> {
//添加权限信息
simpleAuthorizationInfo.addStringPermission(perm.getName());
System.out.println("=========");
System.out.println("用户的权限:"+perm.getName());
});
}
});
return simpleAuthorizationInfo;
}
return null;
}
//用户认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("=======================");
String principal = (String) token.getPrincipal();
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//获取身份信息
User userName = userService.findByUserName(userToken.getUsername());
System.out.println("密码:==========="+ userName.getPassword());
System.out.println("用户名:=============="+userName.getUsername());
if (userName != null){
return new SimpleAuthenticationInfo(userName.getUsername(),userName.getPassword(), ByteSource.Util.bytes(userName.getSalt()),this.getName());
}
return null;
}
}
3.1、shiro的配置。
package com.znzz.springboot_jsp_shiro.config;
import com.znzz.springboot_jsp_shiro.shiro.CustomerRealm;
import com.znzz.springboot_jsp_shiro.shiro.RedisCacheManager;
import lombok.val;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.management.MXBean;
import java.util.HashMap;
import java.util.Map;
/**
* 用来整合shiro的配置类
*/
@Configuration
public class ShiroConfig {
//1.创建shiroFilter
//负责拦截所有请求
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//给filter设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//配置系统的受限资源
Map<String, String> map = new HashMap<String, String>();
map.put("/index.jsp","authc");//authc表示访问这个资源需要认证和授权
map.put("/user/register","anon");
map.put("/register.jsp","anon");//anon表示公共资源,都可以访问的到。
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
//配置系统的公共资源
//默认认证的界面路径,(及你访问没有权限的页面时,会跳转到该页面。)就算你不配置,也会跳转到这个login页面。
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
return shiroFilterFactoryBean;
}
//2.创建安全管理器
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//给安全管理器设置realm
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}
//3.创建自定义realm
@Bean
public Realm getRealm(){
CustomerRealm customerRealm = new CustomerRealm();
//修改凭证校验匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//设置加密算法为md5
credentialsMatcher.setHashAlgorithmName("MD5");
//设置散列次数
credentialsMatcher.setHashIterations(1024);
customerRealm.setCredentialsMatcher(credentialsMatcher);
//开启缓存管理
//shiro默认的缓存管理器,你也可以存入redis中。该项目没有
customerRealm.setCacheManager(new EhCacheManager());
customerRealm.setCachingEnabled(true);// 开启全局缓存
customerRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
customerRealm.setAuthenticationCacheName("authentication");
customerRealm.setAuthorizationCachingEnabled(true);
customerRealm.setAuthorizationCacheName("authorization");//开启授权的缓存
return customerRealm;
}
}
3.2、密码加密工具类
SaltUtils.java
package com.znzz.springboot_jsp_shiro.utils;
import java.util.Random;
import java.util.UUID;
public class SaltUtils {
/**
*
* 随机生成salt
* @param
*/
public static String getSalt( int n){
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabvdefghijklmnopqrstuvwxyz!@#$%^&*012345679".toCharArray();
StringBuilder sb = new StringBuilder();
for (int i=0; i < n; i++){
char aChar = chars[new Random().nextInt(chars.length)];
sb.append(aChar);
}
return sb.toString();
}
完成之后运行调试一下吧。
(1).访问 http://localhost:8080/shiro/index.jsp, 他会自动跳转到登录界面。因为我们给index.jsp这个路径设置了必须要认证才能访问哦!
(2).输入用户名:lsg ;密码: 123 ,登录,你就会发现登录成功,进入index.jsp页面,你能够看到这些东西,是因为你有管理员的权限,(可到数据库自己查看),
(3)…输入用户名:tom;密码: 123 ,登录,你就会发现登录成功,进入index.jsp页面,你能够看到这些东西,是因为你只有用户的权限,(可到数据库自己查看),
另外,在shiro中加了缓存,你会发现,你一直刷新index.jsp页面。控制台不会输出任何东西,(先说名一下,如果你不开启缓存,你每次刷新都会查询数据库,用户的每次权限,角色都会查数据库,导致压力很大,所以才加入缓存。)这是因为我们开启了缓存,只是第一次用户进入系统的时候才会查询数据库,以后就直接查缓存。
最后,如果有不懂的,请查看教程一,shiro教程一地址
如果有错请及时指出,谢谢大家。