Spring boot jpa 整合Shiro 简单权限控制代码逻辑
集成shiro大概分这么一个步骤:
(a) pom.xml中添加Shiro依赖;
(b) 注入Shiro Factory和SecurityManager。
(c) 身份认证
(d) 权限控制
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- shiro权限控制框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
第二步 编写 ShiroConfiguration 代码
package com.test.demo.shiro;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
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 org.apache.shiro.mgt.SecurityManager ;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Configuration
@SuppressWarnings("all")
public class ShiroConfiguration {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager( securityManager);
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/userInfo/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/userInfo/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/assets/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/layui/**", "anon");
filterChainDefinitionMap.put("/captcha/**", "anon");
filterChainDefinitionMap.put("/favicon.ico", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/userInfo/logout", "logout");
// <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
// authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问;
// user:认证通过或者记住了登录状态(remeberMe)则可以通过
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//自定义拦截器
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
filters.put("authc", new MyFormAuthenticationFilter());
return shiroFilterFactoryBean;
}
/**
* 身份认证realm; (这个需要自己写,账号密码校验;权限等)
* @return myShiroRealm
*/
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
/**
* 安全管理器
* @return securityManager
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/**
* 凭证匹配器
* (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* )
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("Md5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
编写 MyFormAuthenticationFilter代码
package com.test.demo.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/19
*/
@SuppressWarnings("all")
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
private static final Logger logger = LoggerFactory.getLogger(MyFormAuthenticationFilter.class);
/**
* 重写该方法, 判断返回登录信息
*/
@Override
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
String className = ae.getClass().getName();
String message;
String userName = getUsername(request);
if (UnknownAccountException.class.getName().equals(className)) {
logger.info("对用户[{}]进行登录验证..验证未通过,未知账户", userName);
message = "账户不存在";
} else if (IncorrectCredentialsException.class.getName().equals(className)) {
logger.info("对用户[{}]进行登录验证..验证未通过,错误的凭证", userName);
message = "密码不正确";
} else if(LockedAccountException.class.getName().equals(className)) {
logger.info("对用户[{}]进行登录验证..验证未通过,账户已锁定", userName);
message = "账户已锁定";
} else if(ExcessiveAttemptsException.class.getName().equals(className)) {
logger.info("对用户[{}]进行登录验证..验证未通过,错误次数过多", userName);
message = "用户名或密码错误次数过多,请十分钟后再试";
} else if (AuthenticationException.class.getName().equals(className)) {
//通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
logger.info("对用户[{}]进行登录验证..验证未通过,未知错误", userName);
message = "用户名或密码不正确";
} else{
message = "";
}
request.setAttribute(getFailureKeyAttribute(), message);
}
}
编写MyShiroRealm代码
package com.test.demo.shiro;
import com.test.demo.domain.SysPermission;
import com.test.demo.domain.SysRole;
import com.test.demo.domain.UserInfo;
import com.test.demo.service.UserInfoService;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@SuppressWarnings("all")
@Configuration
public class MyShiroRealm extends AuthorizingRealm {
private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
@Resource
private UserInfoService userInfoService;
// 权限授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("进入角色授权");
String userName = (String) getAvailablePrincipal(principals);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
UserInfo userInfo = userInfoService.findByUsername(userName) ;
for(SysRole sysRole : userInfoService.findByUsername(userInfo.getUsername()).getRoleList()){
authorizationInfo.addRole(sysRole.getRole());
logger.info(sysRole.toString());
for(SysPermission sysPermission : sysRole.getPermissions()){
logger.info(sysPermission.toString());
authorizationInfo.addStringPermission(sysPermission.getPermission());
}
};
return authorizationInfo;
}
//主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
throws AuthenticationException {
//用户账号
String username = (String) authcToken.getPrincipal();
//根据用户账号从数据库取出盐和加密后的值
//按照固定规则加密码结果 ,此密码 要在数据库存储,原始密码 是111111,盐是eteokues
UserInfo userInfo = userInfoService.findByUsername(username);
String password = userInfo.getPassword();
//盐,随机数,此随机数也在数据库存储
String salt = userInfo.getSalt();
//返回认证信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
username, password, ByteSource.Util.bytes(salt),getName());
return simpleAuthenticationInfo;
}
}
表达能力不行,参考别人的文字描述拷贝下来 大家看看
Shiro的认证过程最终会交由Realm执行,这时会调用Realm的getAuthenticationInfo(token)方法。
该方法主要执行以下操作:
1、检查提交的进行认证的令牌信息
2、根据令牌信息从数据源(通常为数据库)中获取用户信息
3、对用户信息进行匹配验证。
4、验证通过将返回一个封装了用户信息的AuthenticationInfo实例。
5、验证失败则抛出AuthenticationException异常信息。
而在我们的应用程序中要做的就是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doGetAuthenticationInfo (),重写获取用户信息的方法。
既然需要进行身份权限控制,那么少不了创建用户实体类,权限实体类。
在权限管理系统中,有这么几个角色很重要,这个要是不清楚的话,那么就很难理解,我们为什么这么编码了。第一是用户表:在用户表中保存了用户的基本信息,账号、密码、姓名,性别等;
第二是:权限表(资源+控制权限):这个表中主要是保存了用户的URL地址,权限信息;
第三就是角色表:在这个表重要保存了系统存在的角色;
第四就是关联表:用户-角色管理表(用户在系统中都有什么角色,比如admin,vip等),角色-权限关联表(每个角色都有什么权限可以进行操作)。依据这个理论,我们进行来进行编码,很明显的我们第一步就是要进行实体类的创建。在这里我们使用Mysql和JPA进行操作数据库。
package com.test.demo.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Entity
@Table(name = "SysPermission")
public class SysPermission implements Serializable{
@Id
@GeneratedValue
private Long id;//主键.
private String name;//名称.
@Column(columnDefinition="enum('menu','button')")
private String resourceType;//资源类型,[menu|button]
private String url;//资源路径.
private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
private Long parentId; //父编号
private String parentIds; //父编号列表
private Boolean available = Boolean.FALSE;
@ManyToMany
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
private List<SysRole> roles;
...... 省略setter 和 getter 方法 ,大家自己加一下
}
package com.test.demo.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Entity
@Table(name = "SysRole")
public class SysRole implements Serializable{
@Id
@GeneratedValue
private Long id; // 编号
private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
private String description; // 角色描述,UI界面显示使用
private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户
//角色 -- 权限关系:多对多关系;
@ManyToMany(fetch= FetchType.EAGER)
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
private List<SysPermission> permissions;
// 用户 - 角色关系定义;
@ManyToMany
@JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})
private List<UserInfo> userInfos;// 一个角色对应多个用户
...... 省略setter 和 getter 方法 ,大家自己加一下
}
package com.test.demo.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Entity
@Table(name = "UserInfo")
public class UserInfo implements Serializable{
@Id
@GeneratedValue
private Long uid;//用户id;
@Column(unique=true)
private String username;//账号.
private String name;//名称(昵称或者真实姓名,不同系统不同定义)
private String password; //密码;
private String salt;//加密密码的盐
private byte state;//用户状态,0:创建未认证(比如没有**,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
@ManyToMany(fetch=FetchType.EAGER)//立即从数据库中进行加载数据;
@JoinTable(name = "SysUserRole",joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
private List<SysRole> roleList;// 一个用户具有多个角色
...... 省略setter 和 getter 方法 ,大家自己加一下
}
当然 Spring boot 项目 必须要配置application.properties 文件
############################################
## thymeleaf 配置
############################################
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
############################################
## MySQL数据库连接
############################################
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.10.1.26:3306/zhouqmTest?allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=111111
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
############################################
## 配置自动建表:updata:没有表新建,有表更新操作,控制台显示建表语句
############################################
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
server.port= 9090
#LOGGING 日志配置
logging.path=/var/logs
logging.file=myapp.log
logging.level.root=INFO
logging.config=
仓库类
package com.test.demo.repository;
import com.test.demo.domain.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
public interface UserInfoRepository extends CrudRepository<UserInfo,Long> ,JpaRepository<UserInfo, Long> {
UserInfo findByUsername(String username);
}
service 类
package com.test.demo.service;
import com.test.demo.domain.UserInfo;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
public interface UserInfoService {
/**通过username查找用户信息;*/
UserInfo findByUsername(String username);
}
service 实现类
package com.test.demo.service.impl;
import com.test.demo.domain.UserInfo;
import com.test.demo.repository.UserInfoRepository;
import com.test.demo.service.UserInfoService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Resource
private UserInfoRepository userInfoRepository;
@Override
public UserInfo findByUsername(String username) {
System.out.println("UserInfoServiceImpl.findByUsername()");
return userInfoRepository.findByUsername(username);
}
}
@ControllerAdvice
,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强。异常处理类
package com.test.demo.controller;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/20
*/
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = UnauthorizedException.class)//处理访问方法时权限不足问题
public String defaultErrorHandler(HttpServletRequest req, Exception e) {
return "403";
}
}
controller类
package com.test.demo.controller;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* @Description:
* @作者: 周前梅
* @Date: 2018/10/18
*/
@Controller
@RequestMapping("/userInfo")
public class UserInfoController {
private static final Logger logger = LoggerFactory.getLogger(UserInfoController.class);
@RequestMapping("/index")
public String index(){
return "index" ;
}
@RequestMapping("/login")
public String login(HttpServletRequest request , Model model){
if (SecurityUtils.getSubject().isAuthenticated()){
return "redirect:/userInfo/index" ;
}else {
String msg = request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME)+"" ;
System.out.println("msg-----------------------------"+msg);
if (StringUtils.isNotEmpty(msg)) {
model.addAttribute("msg" , msg ) ;
return "login" ;
} else {
return "redirect:/userInfo/index" ;
}
}
}
@RequestMapping(value="/logout")
public String logout(){
//使用权限管理工具进行用户的退出,跳出登录,给出提示信息
SecurityUtils.getSubject().logout();
return "redirect:/userInfo/login";
}
@RequestMapping("/userAdd")
@RequiresPermissions("userInfo:add")//权限管理;
public String userInfoAdd(){
System.out.println("----------------------");
return "userInfoAdd";
}
@RequestMapping("/userDel")
@RequiresPermissions("userInfo:del")//权限管理;
public String userDel() {
System.out.println("----------------------");
return "userInfoDel";
}
}
Spring boot项目 中thymeleaf 会自动找到templates static 所以我们只需要在templates放文件,static放js就行
会涉及5个html 文件 和一个jquery 文件
添加 login.html 文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:c="http://www.w3.org/1999/XSL/Transform">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>登录</title>
<link rel="stylesheet" type="text/css" href="/css/common.css" />
</head>
<body>
<form th:action="@{/userInfo/login}" method="post">
<div>
<!--/*@thymesVar id="error" type=""*/-->
<span id="basic-addon0"> </span>
<a th:if="${msg} != 'null'" >
<span style="font-size: 12px;color: red" th:text="${msg}" aria-describedby="basic-addon0"></span>
</a>
<br />
</div>
<div>
<span id="basic-addon1">@</span>
<input id="username" name="username" type="text" placeholder="用户名" aria-describedby="basic-addon1" />
</div>
<br />
<div>
<span id="basic-addon2">@</span>
<input id="password" name="password" type="password" placeholder="密码" aria-describedby="basic-addon2" />
</div>
<br />
<button type="submit" style="width:190px;">登 录</button>
</form>
</body>
</html>
添加 index.html 文件
<c:set value="${pageContext.request.contextPath}" var="ctx" xmlns:c="http://www.springframework.org/schema/beans"/>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>第一个HTML页面</title>
<script type="text/javascript" src="/jquery-1.8.3.js"></script>
</head>
<body>
<h1>Hello Spring Boot!!!</h1>
<p th:text="${hello}"></p>
<input type="button" id="logout" value="退出登录" />
<script type="text/javascript">
$("#logout").click(function(){
location.href="/userInfo/logout";
});
</script>
</body>
</html>
添加 403.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
您没有权限查看哦
</body>
</html>
添加 userInfoAdd.html 文件
<c:set value="${pageContext.request.contextPath}" var="ctx" xmlns:c="http://www.springframework.org/schema/beans"/>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>第一个HTML页面</title>
<script type="text/javascript" src="/jquery-1.8.3.js"></script>
</head>
<body>
<h1>Hello Spring Boot!!!</h1>
用户添加页面
</body>
</html>
添加 userInfoDel.html 文件
<c:set value="${pageContext.request.contextPath}" var="ctx" xmlns:c="http://www.springframework.org/schema/beans"/>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>第一个HTML页面</title>
<script type="text/javascript" src="/jquery-1.8.3.js"></script>
</head>
<body>
<h1>Hello Spring Boot!!!</h1>
删除用户了,请注意
</body>
</html>
jquery 大家就自己下载下
该写的代码 写好了,现在 重启下服务
jpa 会 自动创建表的 ,然后我们需要在表中 添加几条数据
INSERT INTO `SysPermission` VALUES ('1', '1', '用户管理', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userList');
INSERT INTO `SysPermission` VALUES ('2', '1', '用户添加', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd');
INSERT INTO `SysPermission` VALUES ('3', '1', '用户删除', '1', '0/1', 'userInfo:del', 'button', 'userInfo/userDel');
INSERT INTO `SysRole` VALUES ('1', '1', '管理员', 'admin');
INSERT INTO `SysRole` VALUES ('2', '1', 'VIP会员', 'vip');
INSERT INTO `SysRolePermission` VALUES ('1', '1');
INSERT INTO `SysRolePermission` VALUES ('1', '2');
INSERT INTO `SysUserRole` VALUES ('1', '1');
INSERT INTO `SysUserRole` VALUES ('1', '2');
INSERT INTO `user_info` VALUES (1,'管理员','cb571f7bd7a6f73ab004a70322b963d5','eteokues',0,'admin');
好了,代码都写完毕了,现在 我们来测试下demo
我们输入 用户名密码 admin 111111
这表示我们登录成功了,当然你也可以试下 例如 密码错误 或者账号不存在 各种功能
我们先来看看 权限 功能 访问 用户新增 权限 ,地址是:http://localhost:9090/userInfo/userAdd
可以成功进入 ,再看看用户删除功能 ,地址是:http://localhost:9090/userInfo/userDel
直接提示你没有 权限操作 ,整个逻辑就是这样。
想要源码 私信给我 或者 加qq : 978258922