集成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
直接提示你沒有 權限操作 ,整個邏輯就是這樣。