添加依赖代码如下:
<?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.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-shiro-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>springboot-shiro-1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.15</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建实体类
User
package com.example.springbootshiro1.entity;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
@Entity
public class User implements Serializable {
@Id
@GeneratedValue
private Integer userId;
private String userName;
private String passWord;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "UserRole", joinColumns = {@JoinColumn(name = "userId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")})
private List<Role> roleList;
public User() {
}
public User(Integer userId, String userName, String passWord, List<Role> roleList) {
this.userId = userId;
this.userName = userName;
this.passWord = passWord;
this.roleList = roleList;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return userId.equals(user.userId) &&
userName.equals(user.userName) &&
passWord.equals(user.passWord) &&
roleList.equals(user.roleList);
}
@Override
public int hashCode() {
return Objects.hash(userId, userName, passWord, roleList);
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
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 List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
}
Role
package com.example.springbootshiro1.entity;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
@Entity
public class Role implements Serializable {
@Id
@GeneratedValue
private Integer roleId;
private String roleName;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "RoleMenu", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "menuId")})
private List<Menu> menuList;
@ManyToMany
@JoinTable(name = "UserRole", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "userId")})
private List<User> userList;
public Role() {
}
public Role(Integer roleId, String roleName, List<Menu> menuList, List<User> userList) {
this.roleId = roleId;
this.roleName = roleName;
this.menuList = menuList;
this.userList = userList;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Role role = (Role) o;
return roleId.equals(role.roleId) &&
roleName.equals(role.roleName) &&
menuList.equals(role.menuList) &&
userList.equals(role.userList);
}
@Override
public int hashCode() {
return Objects.hash(roleId, roleName, menuList, userList);
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public List<Menu> getMenuList() {
return menuList;
}
public void setMenuList(List<Menu> menuList) {
this.menuList = menuList;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
Menu
package com.example.springbootshiro1.entity;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
@Entity
public class Menu implements Serializable {
@Id
@GeneratedValue
private Integer menuId;
private String menuName;
@ManyToMany
@JoinTable(name = "RoleMenu", joinColumns = {@JoinColumn(name="menuId")},inverseJoinColumns = {@JoinColumn(name="roleId")})
private List<Role> roleList;
public Menu() {
}
public Menu(Integer menuId, String menuName, List<Role> roleList) {
this.menuId = menuId;
this.menuName = menuName;
this.roleList = roleList;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Menu menu = (Menu) o;
return menuId.equals(menu.menuId) &&
menuName.equals(menu.menuName) &&
roleList.equals(menu.roleList);
}
@Override
public int hashCode() {
return Objects.hash(menuId, menuName, roleList);
}
public Integer getMenuId() {
return menuId;
}
public void setMenuId(Integer menuId) {
this.menuId = menuId;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
}
创建repository
package com.example.springbootshiro1.repository;
import com.example.springbootshiro1.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUserName(String username);
}
创建配置类
MyShiroRealm
package com.example.springbootshiro1.config;
import com.example.springbootshiro1.entity.Menu;
import com.example.springbootshiro1.entity.Role;
import com.example.springbootshiro1.entity.User;
import com.example.springbootshiro1.repository.UserRepository;
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.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
@Configuration
public class MyShiroRealm extends AuthorizingRealm {
@Resource
private UserRepository userRepository;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo simpleAuthorization = new SimpleAuthorizationInfo();
User userInfo = (User) principalCollection.getPrimaryPrincipal();
for (Role role : userInfo.getRoleList()) {
simpleAuthorization.addRole(role.getRoleName());
for (Menu menu: role.getMenuList()) {
simpleAuthorization.addStringPermission(menu.getMenuName());
}
}
return simpleAuthorization;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String userName = (String) authenticationToken.getPrincipal();
User user = userRepository.findByUserName(userName);
if (user == null) {
return null;
}
return new SimpleAuthenticationInfo(user, user.getPassWord(), getName());
}
}
创建ShiroConfig
package com.example.springbootshiro1.config;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
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.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<> ();
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/401");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public MyShiroRealm shiroRealm(){
return new MyShiroRealm();
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
return securityManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager security){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(security);
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.setProperty("DatabaseException", "databaseError");
properties.setProperty("UnauthorizedException", "401");
simpleMappingExceptionResolver.setExceptionMappings(properties);
simpleMappingExceptionResolver.setDefaultErrorView("error");
simpleMappingExceptionResolver.setExceptionAttribute("ex");
return simpleMappingExceptionResolver;
}
}
ShiroController
package com.example.springbootshiro1.config;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
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.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<> ();
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/401");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public MyShiroRealm shiroRealm(){
return new MyShiroRealm();
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
return securityManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager security){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(security);
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.setProperty("DatabaseException", "databaseError");
properties.setProperty("UnauthorizedException", "401");
simpleMappingExceptionResolver.setExceptionMappings(properties);
simpleMappingExceptionResolver.setDefaultErrorView("error");
simpleMappingExceptionResolver.setExceptionAttribute("ex");
return simpleMappingExceptionResolver;
}
}
创建页面,delete,index,401,login,select
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>delete</title>
</head>
<body>
delete
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
index
<br />
<form th:action="@{/logout}" method="post">
<p><input type="submit" value="注销"/></p>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>401</title>
</head>
<body>
401
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
login
<br />
错误信息:<h4 th:text="${msg}"></h4>
<form action="" method="post">
<p>账号:<input type="text" name="username" value="dalaoyang"/></p>
<p>密码:<input type="text" name="password" value="123"/></p>
<p>登陆:<input type="submit" value="登陆"/></p>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
select
</body>
</html>
配置yaml
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
thymeleaf:
cache: false
mode: LEGACYHTML5
启动测试