springboot集成shiro詳細總結
一、項目整體介紹:
項目整體的結構如下圖所示,項目整體采用 springboot + mybatis + jsp + mysql 來完成的,下面會詳細介紹下:


二、數據庫腳本
先在數據庫中創(chuàng)建 user、role、permission 這三張表,table.sql 的內容如下所示:
DROP DATABASE IF EXISTS shiro_test;
CREATE DATABASE shiro_test;
USE shiro_test;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`USER_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`PASSWORD` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`ROLE_IDS` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`STATUS` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ROLE_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`PERMISSIONS_IDS` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`PERMISSION_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
INSERT INTO `shiro_test`.`permission` (`ID`, `PERMISSION_NAME`) VALUES ('1', 'add');
INSERT INTO `shiro_test`.`permission` (`ID`, `PERMISSION_NAME`) VALUES ('2', 'delete');
INSERT INTO `shiro_test`.`permission` (`ID`, `PERMISSION_NAME`) VALUES ('3', 'update');
INSERT INTO `shiro_test`.`permission` (`ID`, `PERMISSION_NAME`) VALUES ('4', 'query');
INSERT INTO `shiro_test`.`role` (`ID`, `ROLE_NAME`, `PERMISSIONS_IDS`) VALUES ('1', 'administrator', '1,2,3,4');
INSERT INTO `shiro_test`.`role` (`ID`, `ROLE_NAME`, `PERMISSIONS_IDS`) VALUES ('2', 'normalUser', '4');
三、maven依賴:
pom.xml 的內容如下所示:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.6.0</version>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>
<!-- 添加shiro web支持 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.6.0</version>
</dependency>
<!-- 簡化model類的setter和getter -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--熱部署依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>priveded</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>priveded</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
四、配置文件:
application.properties 的內容如下所示:
spring.mvc.view.prefix=/page/ spring.mvc.view.suffix=.jsp spring.resources.static-locations=classpath:/page/ spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/shiro_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=true spring.datasource.username=root spring.datasource.password=Rfid123456 mybatis.mapper-locations=classpath*:mapper/*Mapper.xml mybatis.configuration.map-underscore-to-camel-case: true mybatis.configuration.jdbc-type-for-null=null mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl mybatis.configuration.call-setters-on-nulls=true
五、生成pojo:
我這塊使用的是 mybatis 的生成工具自動生成的 entity、dao 和 mapper 文件,我這塊就一并粘出來了,其中,我的 entity 里面的注解比較特殊,如果運行不起來,請參考我的 lombok 的那篇文章,也算是學習了一個新的知識點。
entity 的代碼如下所示:
import java.util.Set;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User {
private Long id;
private String userName;
private String password;
private String roleIds;
private Set<Role> roles;
private String status;
}
import java.util.Set;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Role {
private Long id;
private String roleName;
private String permissionsIds;
private Set<Permission> permissions;
}
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Permission {
public Long id;
public String permissionName;
}
service 層以及其實現類的代碼如下所示:
public interface UserService {
User selectByUserName(String userName);
int insert(User record);
int deleteAll();
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper mapper;
@Autowired
RoleMapper roleMapper;
@Autowired
PermissionMapper permissionsMapper;
@Override
public User selectByUserName(String userName) {
User user = mapper.selectByUserName(userName);
if(user != null) {
Set<Role> roleSet = new HashSet<>();
String [] roleIds = user.getRoleIds().split(",");
for(int i=0;i<roleIds.length;i++) {
Role role = roleMapper.selectByPrimaryKey(Long.valueOf(roleIds[i]));
Set<Permission> permissionsSet = new HashSet<>();
String [] permissionsIds = role.getPermissionsIds().split(",");
for(int j=0;j<permissionsIds.length;j++) {
Permission p = permissionsMapper.selectByPrimaryKey(Long.valueOf(permissionsIds[j]));
permissionsSet.add(p);
}
role.setPermissions(permissionsSet);
roleSet.add(role);
}
user.setRoles(roleSet);
return user;
}
return null;
}
@Override
public int insert(User record) {
return mapper.insert(record);
}
@Override
public int deleteAll() {
return mapper.deleteAll();
}
}
public interface RoleService {
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
RoleMapper mapper;
}
public interface PermissionService {
}
@Service
public class PermissionServiceImpl implements PermissionService {
@Autowired
PermissionMapper mapper;
}
dao 層的代碼如下所示:
@Mapper
public interface UserMapper {
int deleteByPrimaryKey(Long id);
int insert(User record);
User selectByPrimaryKey(Long id);
List<User> selectAll();
int updateByPrimaryKey(User record);
User selectByUserName(String userName);
int deleteAll();
}
@Mapper
public interface RoleMapper {
int deleteByPrimaryKey(Long id);
int insert(Role record);
Role selectByPrimaryKey(Long id);
List<Role> selectAll();
int updateByPrimaryKey(Role record);
}
@Mapper
public interface PermissionMapper {
int deleteByPrimaryKey(Long id);
int insert(Permission record);
Permission selectByPrimaryKey(Long id);
List<Permission> selectAll();
int updateByPrimaryKey(Permission record);
}
mapper.xlm 內容如下所示:
@Mapper
public interface PermissionMapper {
int deleteByPrimaryKey(Long id);
int insert(Permission record);
Permission selectByPrimaryKey(Long id);
List<Permission> selectAll();
int updateByPrimaryKey(Permission record);
}
<?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.dao.RoleMapper">
<resultMap id="BaseResultMap" type="com.entity.Role">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="ROLE_NAME" jdbcType="VARCHAR" property="roleName" />
<result column="PERMISSIONS_IDS" jdbcType="VARCHAR" property="permissionsIds" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from role
where ID = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.entity.Role">
insert into role (ID, ROLE_NAME,PERMISSIONS_IDS)
values (#{id,jdbcType=BIGINT}, #{roleName,jdbcType=VARCHAR}, #{permissionsIds,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey" parameterType="com.entity.Role">
update role
set ROLE_NAME = #{roleName,jdbcType=VARCHAR},
PERMISSIONS_IDS = #{permissionsIds,jdbcType=VARCHAR},
where ID = #{id,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select ID, ROLE_NAME,PERMISSIONS_IDS
from role
where ID = #{id,jdbcType=BIGINT}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select ID, ROLE_NAME,PERMISSIONS_IDS
from role
</select>
</mapper>
<?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.dao.PermissionMapper">
<resultMap id="BaseResultMap" type="com.entity.Permission">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="PERMISSION_NAME" jdbcType="VARCHAR" property="permissionName" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from permission
where ID = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.entity.Permission">
insert into permission (ID, PERMISSION_NAME)
values (#{id,jdbcType=BIGINT}, #{permissionName,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey" parameterType="com.entity.Permission">
update permission
set PERMISSION_NAME = #{permissionName,jdbcType=VARCHAR}
where ID = #{id,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select ID, PERMISSION_NAME
from permission
where ID = #{id,jdbcType=BIGINT}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select ID, PERMISSION_NAME
from permission
</select>
</mapper>
六、插入數據:
我們在初始化的 table.sql 中已經插入了權限和角色的數據,但是用戶的數據的密碼需要加密存儲,所以這塊我們我們采用代碼來插入數據,InsertUser 類的內容如下所示,這段代碼的意思是每次啟動工程的時候先把數據庫里面 user 表的數據清除掉,然后重新插入。
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.entity.User;
import com.service.UserService;
@Component
public class InsertUser implements InitializingBean{
@Autowired
UserService userService;
@Override
public void afterPropertiesSet() throws Exception {
userService.deleteAll();
User user = new User();
// 這里我們假設username+"salt"的值為鹽值。
String salt1 = "zhangsan";
String password1 = "123456";
String encryp_password1 = MD5Pwd(salt1,password1);
user.setUserName(salt1);
user.setPassword(encryp_password1);
user.setRoleIds("1,2");
user.setStatus("1");
userService.insert(user);
User user2 = new User();
String salt2 = "lisi";
String password2 = "123456";
String encryp_password2 = MD5Pwd(salt2,password2);
user2.setUserName(salt2);
user2.setPassword(encryp_password2);
user2.setRoleIds("2");
user2.setStatus("1");
userService.insert(user2);
User user3 = new User();
String salt3 = "wangwu";
String password3 = "123456";
String encryp_password3 = MD5Pwd(salt3,password3);
user3.setUserName(salt3);
user3.setPassword(encryp_password3);
user3.setRoleIds("1");
user3.setStatus("1");
userService.insert(user3);
}
public static String MD5Pwd(String username, String pwd) {
// 加密算法MD5
// 鹽值= username + "salt"
// 迭代次數,這個地方的迭代次數要和后面自定義Relam里面的迭代此時一致
String md5Pwd = new SimpleHash("MD5", pwd,
ByteSource.Util.bytes(username + "salt"), 2).toHex();
return md5Pwd;
}
}
七、自定義Realm:
這里我們自己實現了 CustomRealm,其代碼內容如下所示:
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import com.entity.Permission;
import com.entity.Role;
import com.entity.User;
import com.service.UserService;
public class CustomRealm extends AuthorizingRealm{
@Autowired
UserService userService;
/*
* 權限配置類
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 獲取登錄用戶名
String name = (String)principalCollection.getPrimaryPrincipal();
// 查詢用戶名稱
User user = userService.selectByUserName(name);
// 添加角色和權限
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
List<String> roleNameList = new ArrayList<>();
List<String> permissionNameList = new ArrayList<>();
for (Role role : user.getRoles()) {
roleNameList.add(role.getRoleName());
for (Permission permission : role.getPermissions()) {
permissionNameList.add(role.getRoleName()+":"+permission.getPermissionName());
}
}
// 添加角色
simpleAuthorizationInfo.addRoles(roleNameList);
// 添加權限
simpleAuthorizationInfo.addStringPermissions(permissionNameList);
return simpleAuthorizationInfo;
}
/*
* 認證配置類
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if(StringUtils.isEmpty(authenticationToken.getPrincipal())) {
return null;
}
// 獲取用戶信息
String name = authenticationToken.getPrincipal().toString();
User user = userService.selectByUserName(name);
// 用戶是否存在
if(user == null) {
throw new UnknownAccountException();
}
// 是否激活
if(user !=null && user.getStatus().equals("0")){
throw new DisabledAccountException();
}
// 是否鎖定
if(user!=null && user.getStatus().equals("3")){
throw new LockedAccountException();
}
// 若存在將此用戶存放到登錄認證info中,無需做密碼比對shiro會為我們進行密碼比對校驗
if(user !=null && user.getStatus().equals("1")){
ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUserName()+ "salt");
// 這里驗證authenticationToken和simpleAuthenticationInfo的信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(),credentialsSalt, getName());
return simpleAuthenticationInfo;
}
return null;
}
}
八、配置shiro:
編寫 ShiroConfig 的配置類,內容如下所示:
import java.util.HashMap;
import java.util.Map;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.shiro.CustomRealm;
@Configuration
public class ShiroConfig {
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
// 將自己的驗證方式加入容器
@Bean
public CustomRealm myShiroRealm() {
CustomRealm customRealm = new CustomRealm();
// 告訴realm,使用credentialsMatcher加密算法類來驗證密文
customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
}
// 權限管理,配置主要是Realm的管理認證
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
// Filter工廠,設置對應的過濾條件和跳轉條件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> map = new HashMap<>();
//登出
map.put("/logout", "logout");
//對所有用戶認證
map.put("/**", "authc");
//登錄
shiroFilterFactoryBean.setLoginUrl("/login");
//首頁
shiroFilterFactoryBean.setSuccessUrl("/index");
//錯誤頁面,認證不通過跳轉
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// 散列算法:這里使用MD5算法;
hashedCredentialsMatcher.setHashAlgorithmName("md5");
// 散列的次數,比如散列兩次,相當于 md5(md5(""));
hashedCredentialsMatcher.setHashIterations(2);
// storedCredentialsHexEncoded默認是true,此時用的是密碼加密用的是Hex編碼;false時用Base64編碼
hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
return hashedCredentialsMatcher;
}
}
九、登錄攔截
創(chuàng)建 LoginController 來攔截用戶的前端請求,其代碼內容如下所示:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import com.entity.User;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
public class LoginController {
@RequestMapping("/login")
public String login(User user) {
if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())) {
return "error";
}
//用戶認證信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
user.getUserName(),
user.getPassword());
usernamePasswordToken.setRememberMe(true);
try {
//進行驗證,這里可以捕獲異常,然后返回對應信息
subject.login(usernamePasswordToken);
} catch (UnknownAccountException e) {
log.error("用戶名不存在!", e);
return "error";
} catch (AuthenticationException e) {
log.error("賬號或密碼錯誤!", e);
return "error";
} catch (AuthorizationException e) {
log.error("沒有權限!", e);
return "error";
}
return "shiro_index";
}
}
十、前端展示界面:
前端用戶展示的 shiro_index.jsp 內容如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
<shiro:guest>
<h1>歡迎游客訪問</h1>
</shiro:guest>
</br>
<shiro:user>
<h1>歡迎[<shiro:principal/>]登錄</h1>
</shiro:user>
</br>
<shiro:authenticated>
<h1>用戶[<shiro:principal/>]身份已驗證通過</h1>
</shiro:authenticated>
</br>
<shiro:hasAnyRoles name="administrator,normalUser">
<h2>用戶[<shiro:principal/>]擁有角色administrator或normalUser</h2>
</shiro:hasAnyRoles>
</br>
<shiro:lacksRole name="test">
<h2> 用戶[<shiro:principal/>] 沒有角色test </h2>
</shiro:lacksRole>
</br>
<shiro:hasRole name="administrator">
<h3>擁有administrator的角色才會顯示這個標簽</h3>
</shiro:hasRole>
</br>
<shiro:hasRole name="normalUser">
<h3>擁有normalUser的角色才會顯示這個標簽</h3>
</shiro:hasRole>
</br>
<shiro:hasPermission name="normalUser:query">
<h3>用戶[<shiro:principal/>]擁有權限normalUser:query</h3>
</shiro:hasPermission>
</br>
<shiro:hasPermission name="normalUser:add">
<h3>用戶[<shiro:principal/>]擁有權限normalUser:add</h3>
</shiro:hasPermission>
</br>
<shiro:hasPermission name="administrator:add">
<h3>用戶[<shiro:principal/>]擁有權限administrator:add</h3>
</shiro:hasPermission>
</br>
<shiro:hasPermission name="administrator:delete">
<h3>用戶[<shiro:principal/>]擁有權限administrator:delete</h3>
</shiro:hasPermission>
</br>
<shiro:hasPermission name="administrator:update">
<h3>用戶[<shiro:principal/>]擁有權限administrator:update</h3>
</shiro:hasPermission>
</br>
<shiro:hasPermission name="administrator:query">
<h3>用戶[<shiro:principal/>]擁有權限administrator:query</h3>
</shiro:hasPermission>
</body>
</html>
error.jsp 的內容如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Insert title here</title> </head> <body> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%> <h1>賬號或者密碼錯誤!</h1> </body> </html>
十一、啟動類:
啟動類 App 的代碼內容如下所示:
@SpringBootApplication
@MapperScan({"com.dao"})
public class App {
public static void main( String[] args ){
SpringApplication.run(App.class, args);
}
}
十二、測試:
在瀏覽器輸入:http://localhost:8080/login?userName=zhangsan&password=123456 展示內容如下所示:

在瀏覽器輸入:http://localhost:8080/login?userName=zhangsan&password=123456 內容如下所示:

到此這篇關于springboot集成shiro詳細總結的文章就介紹到這了,更多相關springboot集成shiro內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用自定義注解和@Aspect實現責任鏈模式的組件增強的詳細代碼
責任鏈模式是一種行為設計模式,其作用是將請求的發(fā)送者和接收者解耦,從而可以靈活地組織和處理請求,本文講給大家介紹如何使用自定義注解和@Aspect實現責任鏈模式的組件增強,文中有詳細的代碼示例供大家參考,感興趣的同學可以借鑒一下2023-05-05
ServletContext讀取web資源_動力節(jié)點Java學院整理
這篇文章主要介紹了ServletContext讀取web資源,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
httpclient ConnectionHolder連接池連接保持源碼解析
這篇文章主要為大家介紹了httpclient ConnectionHolder連接池連接保持源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11
Spring context:component-scan的使用及說明
這篇文章主要介紹了Spring context:component-scan的使用及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Java+ElasticSearch+Pytorch實現以圖搜圖功能
這篇文章主要為大家詳細介紹了Java如何利用ElasticSearch和Pytorch實現以圖搜圖功能,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下2023-06-06

