这篇文章主要介绍了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=.jspspring.resources.static-locations=classpath:/page/ spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/shiro_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=truespring.datasource.username=rootspring.datasource.password=Rfid123456 mybatis.mapper-locations=classpath*:mapper@Overrideprotected 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;} @Overrideprotected 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; @Configurationpublic class ShiroConfig { @Bean@ConditionalOnMissingBeanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();defaultAAP.setProxyTargetClass(true);return defaultAAP;} // 将自己的验证方式加入容器@Beanpublic CustomRealm myShiroRealm() {CustomRealm customRealm = new CustomRealm();// 告诉realm,使用credentialsMatcher加密算法类来验证密文customRealm.setCredentialsMatcher(hashedCredentialsMatcher());return customRealm;} // 权限管理,配置主要是Realm的管理认证@Beanpublic SecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(myShiroRealm());return securityManager;}// Filter工厂,设置对应的过滤条件和跳转条件@Beanpublic 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;} @Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}@Beanpublic 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@Slf4jpublic 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><h2>欢迎游客访问</h2></shiro:guest></br><shiro:user><h2>欢迎[<shiro:principal/>]登录</h2></shiro:user></br><shiro:authenticated><h2>用户[<shiro:principal/>]身份已验证通过</h2></shiro:authenticated></br><shiro:hasAnyRoles name="administrator,normalUser"><h3>用户[<shiro:principal/>]拥有角色administrator或normalUser</h3></shiro:hasAnyRoles></br><shiro:lacksRole name="test"> <h3> 用户[<shiro:principal/>] 没有角色test </h3></shiro:lacksRole></br><shiro:hasRole name="administrator"> <h4>拥有administrator的角色才会显示这个标签</h4></shiro:hasRole></br><shiro:hasRole name="normalUser"> <h4>拥有normalUser的角色才会显示这个标签</h4></shiro:hasRole></br><shiro:hasPermission name="normalUser:query"><h4>用户[<shiro:principal/>]拥有权限normalUser:query</h4></shiro:hasPermission></br><shiro:hasPermission name="normalUser:add"><h4>用户[<shiro:principal/>]拥有权限normalUser:add</h4></shiro:hasPermission></br><shiro:hasPermission name="administrator:add"><h4>用户[<shiro:principal/>]拥有权限administrator:add</h4></shiro:hasPermission></br><shiro:hasPermission name="administrator:delete"><h4>用户[<shiro:principal/>]拥有权限administrator:delete</h4></shiro:hasPermission></br><shiro:hasPermission name="administrator:update"><h4>用户[<shiro:principal/>]拥有权限administrator:update</h4></shiro:hasPermission></br><shiro:hasPermission name="administrator:query"><h4>用户[<shiro:principal/>]拥有权限administrator:query</h4></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"%> <h2>账号或者密码错误!</h2> </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是什么
springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,SpringBoot也是一个服务于框架的框架,服务范围是简化配置文件。
感谢你能够认真阅读完这篇文章,希望小编分享的“springboot如何集成shiro”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!