1. 程式人生 > >SpringBoot整合Shiro登入認證和授權(附demo)

SpringBoot整合Shiro登入認證和授權(附demo)

SpringBoot整合Shiro登入認證和授權

廢話不多說,直接上程式碼:
程式碼有點多,想直接拿demo的直接拉到底

ps:demo忘了在哪拿的了,在他的基礎上改了一些
在這裡插入圖片描述

步驟一:pom.xml匯入依賴jar包

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<!--<scope>provided</scope>-->
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- SpringBoot中使用 Shiro 做使用者、角色、許可權管理 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.4.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		
		<!-- swagger生成介面API -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.7.0</version>
		</dependency>
		<!-- 介面API生成html文件 -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.6.1</version>
		</dependency>
	</dependencies>

步驟二:ShiroConfig配置類

package com.cun.config;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.apache.shiro.mgt.SecurityManager;
import com.cun.realm.MyRealm;

/**
 * Shiro配置類
 * @author linhongcun
 *
 */
@Configuration
public class ShiroConfig {
	/**
	 * ShiroFilterFactoryBean 處理攔截資原始檔問題。
	 * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以為在
	 * 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
	 *
	 * Filter Chain定義說明 :
	 * 1、一個URL可以配置多個Filter,使用逗號分隔
	 * 2、當設定多個過濾器時,全部驗證通過,才視為通過
	 * 3、部分過濾器可指定引數,如perms,roles
	 * Filter工廠,設定對應的過濾條件和跳轉條件
	 */
	@Bean
	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		// 必須設定 SecurityManager
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 如果不設定預設會自動尋找Web工程根目錄下的"/login.jsp"頁面
		shiroFilterFactoryBean.setLoginUrl("/login.html");
		// 攔截器.
		Map<String, String> map = new LinkedHashMap<String, String>();
		// 配置不會被攔截的連結 順序判斷
		map.put("/static/**", "anon");
		map.put("/user/login", "anon");
		//測試許可權用
		map.put("/swagger-ui.html", "anon");

		// 配置退出過濾器,其中的具體的退出程式碼Shiro已經替我們實現了
		map.put("/logout", "logout");

		// 過濾鏈定義,從上向下順序執行,一般將 /**放在最為下邊 :這是一個坑呢,一不小心程式碼就不好使了;
		// ① authc:所有url都必須認證通過才可以訪問; ② anon:所有url都都可以匿名訪問
		map.put("/**","authc");

		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}

	/**
	 * 許可權管理,配置主要是Realm的管理認證
	 * @return
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		// 設定realm.
		securityManager.setRealm(myRealm());
		return securityManager;
	}

	/**
	 * 身份認證realm; (這個需要自己寫,賬號密碼校驗;許可權等)
	 * 將自己的驗證方式加入容器
	 * @return
	 */
	@Bean
	public MyRealm myRealm() {
		MyRealm myRealm = new MyRealm();
		return myRealm;
	}

	/**
	 * Shiro生命週期處理器
	 * @return
	 */
	@Bean
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	/**
	 * 開啟Shiro的註解(如@RequiresRoles,@RequiresPermissions),需藉助SpringAOP掃描使用Shiro註解的類,並在必要時進行安全邏輯驗證
	 * 配置以下兩個bean(DefaultAdvisorAutoProxyCreator(可選)和AuthorizationAttributeSourceAdvisor)即可實現此功能
	 * @return
	 */
	@Bean
	@DependsOn({ "lifecycleBeanPostProcessor" })
	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
		return authorizationAttributeSourceAdvisor;
	}
}

步驟三:UserController類

package com.cun.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cun.entity.User;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2
@RestController
@RequestMapping("/user")
public class UserController {

	@PostMapping("/login")
	public Map<String, Object> login(@Valid User user, BindingResult bindingResult, HttpSession session) {
		Map<String, Object> map = new HashMap<String, Object>();

		// 1、JSR303
		if (bindingResult.hasErrors()) {
			map.put("success", false);
			map.put("errorInfo", bindingResult.getFieldError().getDefaultMessage());
			return map;
		}

		// 2、Shiro
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());
		try {
			subject.login(token);
			map.put("success", true);
			return map;
		} catch (Exception e) {
			e.printStackTrace();
			map.put("success", false);
			map.put("errorInfo", "使用者名稱或者密碼錯誤!");
			return map;
		}
	}

	@RequiresPermissions({"select"}) //沒有的話 AuthorizationException
	@PostMapping("/select")
	public Map<String, Object> selectPermission() {
		System.out.println("select");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前角色有檢視的權力");
		return map;
	}
	
	@RequiresPermissions({"insert"}) //沒有的話 AuthorizationException
	@PostMapping("/insert")
	public Map<String, Object> insertPermission() {
		System.out.println("insert");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前角色有增加的權力");
		return map;
	}

	@RequiresPermissions({"update"}) //沒有的話 AuthorizationException
	@PostMapping("/update")
	public Map<String, Object> updatePermission() {
		System.out.println("update");
		Map<String, Object> map = null;
		map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前角色有更新的權力");
		return map;
	}

	@RequiresPermissions({"delete"}) //沒有的話 AuthorizationException
	@PostMapping("/delete")
	public Map<String, Object> deletePermission() {
		System.out.println("delete");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前角色有刪除的權力");
		return map;
	}
	
	@RequiresRoles({"vip"}) //沒有的話 AuthorizationException
	@PostMapping("/vip")
	public Map<String, Object> vipRole() {
		System.out.println("vip");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前使用者具有 vip 角色");
		return map;
	}
	
	@RequiresRoles({"ip"}) //沒有的話 AuthorizationException
	@PostMapping("/ip")
	public Map<String, Object> ipRole() {
		System.out.println("ip");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前使用者具有 ip 角色");
		return map;
	}
	
	@RequiresRoles({"p"}) //沒有的話 AuthorizationException
	@PostMapping("/p")
	public Map<String, Object> pRole() {
		System.out.println("vip");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", true);
		map.put("msg", "當前使用者具有 p 角色");
		return map;
	}

	/**
	 * 捕獲沒有許可權時的異常
	 * @return
	 */
	@ExceptionHandler({ UnauthorizedException.class, AuthorizationException.class })
	public Map<String, Object> authorizationException(){
		Map<String, Object> map = new HashMap<String, Object>();
		System.out.println("沒有許可權");
		map.put("success", true);
		map.put("msg", "當前使用者沒有此許可權");
		return map;
	}
}

步驟四:PermissionDao介面類

package com.cun.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.cun.entity.Permission;

public interface PermissionDao extends JpaRepository<Permission, Integer>{
	
	@Query(nativeQuery=true,value="select p.* from t_user u,t_user_role ur,t_role_permission rp,t_permission p where u.id=ur.user_id and ur.role_id=rp.role_id and rp.permission_id=p.id and u.user_name=?1")
	List<Permission> getPermissionsByUserName(String userName);

}

步驟五:RoleDao介面類

package com.cun.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.cun.entity.Role;

public interface RoleDao extends JpaRepository<Role, Integer>{
	
	@Query(value="SELECT r.* FROM t_user_role ur,t_role r,t_user u WHERE u.`id`=ur.`user_id` AND ur.`role_id`=r.`id` AND u.`user_name` = ?1",nativeQuery=true)
	List<Role> getRolesByUserName(String userName);

}

步驟六:UserDao介面類

package com.cun.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.cun.entity.User;

public interface UserDao extends JpaRepository<User, Integer>{
	
	/**
	 * 登入的時候,根據使用者名稱獲取使用者實體
	 * @param userName
	 * @return
	 */
	@Query(value="select * from t_user where user_name=?1",nativeQuery=true)
	public User getUserByUserName(String userName);
}

步驟七:Permission實體類

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_permission")
public class Permission {

	@Id
	@GeneratedValue
	private Integer id; // 編號

	@Column(length = 50)
	private String permissionName; // 選單名稱

	@Column(length = 1000)
	private String remarks; // 備註

	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getPermissionName() {
		return permissionName;
	}

	public void setPermissionName(String permissionName) {
		this.permissionName = permissionName;
	}

	public Permission() {
		super();
	}

}

步驟八:Role實體類

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_role")
public class Role {

	@Id
	@GeneratedValue
	private Integer id; // 編號

	@Column(length = 100)
	private String roleName; // 角色名稱

	@Column(length = 1000)
	private String remarks; // 備註
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getRoleName() {
		return roleName;
	}

	public void setRoleName(String roleName) {
		this.roleName = roleName;
	}

	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	public Role() {
		super();
	}

}

步驟九:RolePermission實體類

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "t_role_permission")
public class RolePermission {

	@Id
	@GeneratedValue
	private Integer id; // 編號

	@ManyToOne
	@JoinColumn(name = "role_id")
	private Role role; // 角色

	@ManyToOne
	@JoinColumn(name = "permission_id")
	private Permission menu; // 選單

	@Column(length = 1000)
	private String remarks; // 備註
	
	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public Permission getMenu() {
		return menu;
	}

	public void setMenu(Permission menu) {
		this.menu = menu;
	}

	public RolePermission() {
		super();
	}

}

步驟十:User類

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name = "t_user")
public class User {

	@Id
	@GeneratedValue
	private Integer id;

	@Column(length = 100)
	@NotEmpty(message = "使用者名稱不能為空")
	private String userName;  //使用者名稱

	@Column(length = 100)
	@NotEmpty(message = "密碼不能為空")
	private String password;  //密碼
	
	@Column(length = 1000)
	private String remarks; // 備註
	
	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public User() {
		super();
	}

}

步驟十一:UserRole類

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "t_user_role")
public class UserRole {

	@Id
	@GeneratedValue
	private Integer id; // 編號

	@ManyToOne
	@JoinColumn(name = "user_id")
	private User user; // 使用者

	@ManyToOne
	@JoinColumn(name = "role_id")
	private Role role; // 角色

	@Column(length = 1000)
	private String remarks; // 備註
	
	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public UserRole() {
		super();
	}

}

步驟十二:MyRealm類

package com.cun.realm;

import java.util.*;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
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.springframework.beans.factory.annotation.Autowired;

import com.cun.dao.PermissionDao;
import com.cun.dao.RoleDao;
import com.cun.dao.UserDao;
import com.cun.entity.Permission;
import com.cun.entity.Role;
import com.cun.entity.User;

public class MyRealm extends AuthorizingRealm {

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private RoleDao roleDao;

	@Autowired
	private PermissionDao permissionDao;
	
	/**
	 * 授權
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
			//獲取token的主身份(登入的username
			String userName=(String) SecurityUtils.getSubject().getPrincipal();
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			Set<String> roles=new HashSet<String>();
			List<Role> rolesByUserName = roleDao.getRolesByUserName(userName);
			for(Role role:rolesByUserName) {
				roles.add(role.getRoleName());
			}
			List<Permission> permissionsByUserName = permissionDao.getPermissionsByUserName(userName);
			for(Permission permission:permissionsByUserName) {
				info.addStringPermission(permission.getPermissionName());
			}
			info.setRoles(roles);
			info.addRoles(roles);
			System.out.println("列印"+info.getStringPermissions().toString());
		    return info;
	}

	/**
	 * 認證
	 */
	@Override                                           //token是使用者輸入的
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("token.getPrincipal:" + token.getPrincipal());
		System.out.println("token.getCredentials:" + token.getCredentials());
		//從token中取出使用者名稱
		String userName = token.getPrincipal().toString();
		//根據使用者名稱從資料庫查詢
		User user = userDao.getUserByUserName(userName);
		if (user != null) {
			// Object principal, Object credentials, String realmName
			AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName());
			// 如果查詢到返回認證資訊authcInfo
			return authcInfo;
		} else {
			return null;
		}
	}

}

步驟十三:application.yml類

server:
  port: 80 #為了以後訪問專案不用寫埠號
  context-path: / #為了以後訪問專案不用寫專案名
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/text?useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf-8  #解決中文亂碼的問題
    username: root
    password: 111111
  jpa: 
    hibernate:
      ddl-auto: update  #資料庫同步程式碼
    show-sql: true      #dao操作時,顯示sql語句

步驟十四:SQL

/*
SQLyog Professional v12.09 (64 bit)
MySQL - 5.7.20-log : Database - text
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @[email protected]@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`text` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `text`;

/*Table structure for table `t_permission` */

DROP TABLE IF EXISTS `t_permission`;

CREATE TABLE `t_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `permission_name` varchar(50) DEFAULT NULL,
  `remarks` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `t_permission` */

insert  into `t_permission`(`id`,`permission_name`,`remarks`) values (1,'select','查詢'),(2,'insert','增加'),(3,'update','更新'),(4,'delete','刪除');

/*Table structure for table `t_role` */

DROP TABLE IF EXISTS `t_role`;

CREATE TABLE `t_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `remarks` varchar(1000) DEFAULT NULL,
  `role_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `t_role` */

insert  into `t_role`(`id`,`remarks`,`role_name`) values (1,'普通角色','p'),(2,'重要角色','ip'),(3,'超級角色','vip');

/*Table structure for table `t_role_permission` */

DROP TABLE IF EXISTS `t_role_permission`;

CREATE TABLE `t_role_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `remarks` varchar(1000) DEFAULT NULL,
  `permission_id` int(11) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKjobmrl6dorhlfite4u34hciik` (`permission_id`),
  KEY `FK90j038mnbnthgkc17mqnoilu9` (`role_id`),
  CONSTRAINT `FK90j038mnbnthgkc17mqnoilu9` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`),
  CONSTRAINT `FKjobmrl6dorhlfite4u34hciik` FOREIGN KEY (`permission_id`) REFERENCES `t_permission` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

/*Data for the table `t_role_permission` */

insert  into `t_role_permission`(`id`,`remarks`,`permission_id`,`role_id`) values (1,'授予普通角色select許可權',1,1),(2,'授予重要角色select許可權',1,2),(3,'授予重要角色insert許可權',2,2),(4,'授予超級角色select許可權',1,3),(5,'授予超級角色insert許可權',2,3),(6,'授予超級角色update許可權',3,3),(7,'授予重要角色update許可權',3,2);

/*Table structure for table `t_user` */

DROP TABLE IF EXISTS `t_user`;

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `password` varchar(100) NOT NULL,
  `remarks` varchar(1000) DEFAULT NULL,
  `user_name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `t_user` */

insert  into `t_user`(`id`,`password`,`remarks`,`user_name`) values (1,'123','jking團隊','jking'),(2,'123','網維團隊','wteam'),(3,'123','ITAEM團隊','itaem');

/*Table structure for table `t_user_role` */

DROP TABLE IF EXISTS `t_user_role`;

CREATE TABLE `t_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `remarks` varchar(1000) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKa9c8iiy6ut0gnx491fqx4pxam` (`role_id`),
  KEY `FKq5un6x7ecoef5w1n39cop66kl` (`user_id`),
  CONSTRAINT `FKa9c8iiy6ut0gnx491fqx4pxam` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`),
  CONSTRAINT `FKq5un6x7ecoef5w1n39cop66kl` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `t_user_role` */

insert  into `t_user_role`(`id`,`remarks`,`role_id`,`user_id`) values (1,'授予JKing團隊普通角色',1,1),(2,'授予網維團隊重要角色',2,2),(3,'授予ITAEM團隊超級角色',3,3),(4,'授予網維團隊普通角色',1,2);

/*!40101 SET [email protected]_SQL_MODE */;
/*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */;
/*!40014 SET [email protected]_UNIQUE_CHECKS */;
/*!40111 SET [email protected]_SQL_NOTES */;

步驟十五:login.html

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>登入頁面</title>
		<link rel="stylesheet" href="static/layui/css/layui.css" />
		<script type="text/javascript" src="static/js/jquery-1.7.2.js"></script>
		<style type="text/css">

		</style>
	</head>

	<body>
		<br />
		<div class="layui-form-item">
			<label class="layui-form-label">使用者名稱:</label>
			<div class="layui-input-block">
				<!-- 1、引數必須被命名為 userName,不能為 username,保持和實體中的屬性一致 -->
				<input type="text" id="userName" name="userName" placeholder="userName" class="layui-input" autocomplete="off"><br/>
			</div>

			<label class="layui-form-label">密碼:</label>
			<div class="layui-input-block">
				<!-- 2、同理密碼引數必須被命名為 password -->
				<input type="password" id="password" name="password" placeholder="password" class="layui-input"><br/>
			</div>
		</div>

		<div class="layui-form-item">
			<div class="layui-input-block">
				<input type="submit" id="loginBtn" value="登入" class="layui-btn"></input>
			</div>
		</div>
	</body>
	
	<script type="text/javascript">
		$("#loginBtn").click(function() {
			$.post("http://localhost/user/login", {
				userName: $("#userName").val(),
				password: $("#password").val(),
			}, function(result) {
				if(result.success) {
					window.location.href = "main.html";
					//必須加上,否則跳轉不了
					return false;
				} else {
					alert(result.errorInfo);
				}
			});

		});
	</script>

</html>

步驟十六:main.html

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>主頁</title>
		<link rel="stylesheet" href="static/layui/css/layui.css" />
		<script type="text/javascript" src="static/js/jquery-1.7.2.js"></script>
		<style type="text/css">
			body {
				margin: 50px;
			}
		</style>
	</head>

	<body>
		
		<button id="selectBtn" class="layui-btn layui-btn-sm layui-btn-radius layui-bg-cyan">
			<i class="layui-icon">&#xe602;</i>select
		</button>
		<button id="insertBtn" class="layui-btn layui-btn-normal layui-btn-sm layui-btn-radius">
			<i class="layui-icon">&#xe654;</i>insert
		</button>
		<button id="updateBtn" class="layui-btn layui-btn-warm layui-btn-sm layui-btn-radius">
			<i class="layui-icon">&#xe642;</i>update
		</button>
		<button id="deleteBtn" class="layui-btn layui-btn-danger layui-btn-sm layui-btn-radius">
			<i class="layui-icon">&#xe640;</i>delete
		</button>

		<hr />
		<button id="vipBtn" class="layui-btn layui-btn-lg">
			vip
		</button>
		<button id="ipBtn" class="layui-btn layui-btn-lg">
			ip
		</button>
		<button id="pBtn" class="layui-btn layui-btn-lg">
			p
		</button>
		
		<hr/>
		<a class="layui-btn layui-btn-sm layui-btn-primary" href="logout">登出</a>
	</body>
	<script type="text/javascript">
		$("#selectBtn").click(function() {
			$.post("http://localhost/user/select", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert(result.errorInfo);
					return false;
				}
			});
		});

		$("#insertBtn").click(function() {
			$.post("http://localhost/user/insert", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert(result.errorInfo);
					return false;
				}
			});
		});

		$("#updateBtn").click(function() {
			$.post("http://localhost/user/update", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert(result.msg);
					return false;
				}
			});
		});

		$("#deleteBtn").click(function() {
			$.post("http://localhost/user/delete", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert(result.errorInfo);
					return false;
				}
			});
		});

		$("#vipBtn").click(function() {
			$.post("http://localhost/user/vip", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert('無權訪問');
					return false;
				}
			});
		});

		$("#ipBtn").click(function() {
			$.post("http://localhost/user/ip", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert('無權訪問');
					return false;
				}
			});
		});
		$("#pBtn").click(function() {
			$.post("http://localhost/user/p", {}, function(result) {
				if(result.success) {
					alert(result.msg);
					return false;
				} else {
					alert('無權訪問');
					return false;
				}
			});
		});
	</script>

</html>

SpringBoot整合Shiro許可權管理原始碼