springboot集成shiro詳細總結
一、項目整體介紹:
項目整體的結構如下圖所示,項目整體采用 springboot + mybatis + jsp + mysql 來完成的,下面會詳細介紹下:
二、數據庫腳本
先在數據庫中創建 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; } }
九、登錄攔截
創建 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內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Shiro:自定義Realm實現權限管理方式
- SpringBoot整合MyBatis超詳細教程
- springboot整合Shiro的步驟
- 搭建MyBatis-Plus框架並進行數據庫增刪改查功能
- SpringBoot MyBatis簡單快速入門例子