基于SpringBoot2的Shiro最简配置操作(两个文件)
更新时间:2021年1月26日 19:46 点击:1709
基础环境:依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.4.0</version> </dependency>
如果不是前后端分离,要实现页面级的权限控制,则加入以下依赖就可以使用shiro的权限标签了(记得在html头部加上相应约束:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="Thymeleaf" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro" lang="en"> ): <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
Realm:认证鉴权器
package com.rz.monomer.modules.shiro; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.rz.monomer.modules.user.entity.SysUserInfo; import com.rz.monomer.modules.user.entity.SysUserRole; import com.rz.monomer.modules.user.service.SysButtonInfoService; import com.rz.monomer.modules.user.service.SysUserInfoService; import com.rz.monomer.modules.user.service.SysUserRoleService; import lombok.extern.slf4j.Slf4j; 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 java.util.Set; import java.util.stream.Collectors; /** * 认证、鉴权类(必须) * * @author sunziwen * @version 1.0 * @date 2019/11/14 14:06 **/ @Slf4j public class ShiroRealm extends AuthorizingRealm { //以下三个服务是普通Dao查询,从数据库查询用户及其角色权限信息(这个类没有自动注入,需要在下个文件中手动注入) private SysUserInfoService userInfoService; private SysButtonInfoService buttonInfoService; private SysUserRoleService userRoleService; public ShiroRealm(SysUserInfoService userInfoService, SysButtonInfoService buttonInfoService, SysUserRoleService userRoleService) { this.userInfoService = userInfoService; this.buttonInfoService = buttonInfoService; this.userRoleService = userRoleService; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { log.info("check authorization info"); SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo(); // 获取当前用户 SysUserInfo userInfo = (SysUserInfo) principals.getPrimaryPrincipal(); // 查询角色信息 Set<Long> userRoles = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userInfo.getId())) .stream() .map(SysUserRole::getRoleId) .collect(Collectors.toSet()); //角色所有权限 Set<String> perms = buttonInfoService.getPermsByRoles(userRoles); authInfo.addStringPermissions(perms); return authInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { log.info("check authentication info"); String username = (String) token.getPrincipal(); // 获取用户信息 SysUserInfo user = userInfoService.getOne(new LambdaQueryWrapper<SysUserInfo>().eq(SysUserInfo::getUsername, username)); if (user == null) { return null; } /*SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(654321), getName());*/ SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), getName()); return authenticationInfo; } }
WebSecurityManager:安全管理器
package com.rz.monomer.modules.shiro; import com.rz.monomer.modules.user.service.SysButtonInfoService; import com.rz.monomer.modules.user.service.SysUserInfoService; import com.rz.monomer.modules.user.service.SysUserRoleService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.apache.shiro.web.filter.authc.LogoutFilter; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; /** * Shiro配置类(必须) * * @author sunziwen * @version 1.0 * @date 2019/11/14 14:08 **/ @Configuration @Slf4j @AllArgsConstructor public class WebSecurityManager { private SysUserInfoService userInfoService; private SysButtonInfoService buttonInfoService; private SysUserRoleService userRoleService; /** * 安全管理器 */ @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm()); return securityManager; } /** * 认证鉴权器(安全管理器的依赖) */ @Bean public ShiroRealm realm() { return new ShiroRealm(userInfoService, buttonInfoService, userRoleService); } /** * 配置拦截规则 */ @Bean public ShiroFilterFactoryBean filter(org.apache.shiro.mgt.SecurityManager securityManager) { log.info("config shiro filter"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); // 定义URL拦截链 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 允许匿名用户访问首页 filterChainDefinitionMap.put("/shiro/index", "anon"); // 定义注销路径 filterChainDefinitionMap.put("/shiro/logout", "logout"); // 所有用户界面都需要身份验证,否则会跳转到loginurl,由FormAuthenticationFilter处理 filterChainDefinitionMap.put("/shiro/user/**", "authc"); // 为login路径定义拦截,由FormAuthenticationFilter处理 filterChainDefinitionMap.put("/shiro/login", "authc"); // 所有vip路径要求具备vip角色权限 filterChainDefinitionMap.put("/shiro/vip/**", "roles[vip]"); // 指定loginurl 路径 shiroFilterFactoryBean.setLoginUrl("/shiro/login"); // 登录成功后跳转路径 shiroFilterFactoryBean.setSuccessUrl("/shiro/user/"); // for un authenticated shiroFilterFactoryBean.setUnauthorizedUrl("/shiro/unauth"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); // 自定义filters,可覆盖默认的Filter列表,参考 DefaultFilter Map<String, Filter> filters = new LinkedHashMap<String, Filter>(); // 定制logout 过滤,指定注销后跳转到登录页(默认为根路径) LogoutFilter logoutFilter = new LogoutFilter(); logoutFilter.setRedirectUrl("/shiro/login"); filters.put("logout", logoutFilter); // 定制authc 过滤,指定登录表单参数 FormAuthenticationFilter authFilter = new FormAuthenticationFilter(); authFilter.setUsernameParam("username"); authFilter.setPasswordParam("password"); filters.put("authc", authFilter); shiroFilterFactoryBean.setFilters(filters); return shiroFilterFactoryBean; } }
Test:登录测试
package com.rz.monomer.modules.user.controller; import com.rz.monomer.commons.utils.Md5Encrypt; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @RestController @Slf4j public class LoginController { @PostMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password) { Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken(username, Md5Encrypt.md5(password)); try { // 执行登录 subject.login(token); } catch (UnknownAccountException e) { // 未知用户 log.warn("the account {} is not found", username); return "account not found"; } catch (IncorrectCredentialsException e) { // 用户或密码不正确 log.warn("the account or password is not correct"); return "account or password not correct"; } return "login success"; } }
补充:SpringBoot配置Shiro时踩坑
在SpringBoot2.0整合shiro时使用@EnableAutoConfiguration的时候需要对config文件进行扫描,即使用@ComponentScan对配置进行扫描。
或者直接使用@SpringBootApplication,但是这种方法会将主方法目录下的所有package都进行扫描影响项目效率。
Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - zxc, rememberMe=false]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException
当出现此异常时,一般情况是用户名密码不匹配,或者是在配置对应的Realm时出现空值导致匹配失败。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。如有错误或未考虑完全的地方,望不吝赐教。
上一篇: java绘制五子棋棋盘
相关文章
IntelliJ IDEA2021.1 配置大全(超详细教程)
这篇文章主要介绍了IntelliJ IDEA2021.1 配置大全(超详细教程),需要的朋友可以参考下...2021-04-18- VPN可以虚拟出一个专用网络,让远处的计算机和你相当于处在同一个局域网中,而中间的数据也可以实现加密传输,用处很大,特别是在一些大公司,分公司处在不同的区域。...2016-01-27
- 这篇文章主要介绍了Tomcat配置及如何在Eclipse中启动,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-04
- 如果我们需要安培Laravel4的话最php最低要求要在php5.3.7版本并且我们需要把mcrypt与openss这两个扩展开启才可以,具体步骤我们参考下文。 前面我们介绍我了 com...2016-11-25
详解Maven profile配置管理及激活profile的几种方式
这篇文章主要介绍了详解Maven profile配置管理及激活profile的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26- 这篇文章主要介绍了IDEA如何添加配置文件到classpath中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
- 通常php.ini的位置在:复制代码 代码如下:/etc目录下或/usr/local/lib目录下。如果你还是找不到php.ini或者找到了php.ini修改后不生效(其实是没找对),请使用如下办法:1.新建php文件,写入如下代码复制代码 代码如下:<?phpe...2014-05-31
- 以下就是部署PHP时的4个配置修改说明,大家一个一个进行学习研究。1、short_open_tag 是什么呢? 决定是否允许使用代码开始标志的缩写形式(<? ?> )。如果要和 XML 结合使用PHP,可以禁用此选项以便于嵌入使用<?x...2015-10-21
- 在使用vue-router的项目中,实例化VueRouter是其配置选项routes该选项指定路由与视图的组件的关系或者路由与其他路由的关系,Router配置选项中是其中最重要的配置。本文就详细的介绍一下...2021-10-25
华为畅享20Pro配置怎么样?华为畅享20Pro参数配置分析
华为畅享20Pro配置怎么样?对于即将上市的华为畅享20 Pro手机,很多的网友们也是相当关注的,大家都想要知道这款华为畅享20 Pro手机的配置到底怎么样,赶紧看看吧...2020-06-29- vue项目中有一些方法需要在多个页面调用,但为了避免在每个页面都import进来,可以把方法加到原型上去,这样在每个组件中都能使用了,下面这篇文章主要给大家介绍了关于配置vue全局方法的两种方式,需要的朋友可以参考下...2021-09-13
详解element-ui 表单校验 Rules 配置 常用黑科技
这篇文章主要介绍了element-ui 表单校验 Rules 配置 常用黑科技,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11tomcat9 下载安装和配置+整合到eclipse的教程详解
这篇文章主要介绍了tomcat9 下载安装和配置+整合到eclipse,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-28- 这篇文章主要介绍了pytest配置文件pytest.ini的详细使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
- 今天研究了个开源项目,数据库是mysql的,其中的脚本数据需要备份,由于本人的机器时mac pro,而且mac下的数据库连接工具都不怎么好用,就想着如何利用windows下的数据库连接工具使用,并做相关备份,另外windows系统下的sqlyo...2015-10-21
- 这篇文章主要介绍了vue配置多代理服务接口地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-08
mysql(master/slave)主从复制原理及配置图文详解
这篇文章主要介绍了mysql(masterslave)主从复制原理及配置图文详解,以前脚本之家小编发过相关的内容,但这么好的非常少见特分享一下,需要的朋友可以参考下...2016-06-12- 这篇文章主要介绍了springboot中nacos动态路由的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
- 系统:centos 5.9 环境:apache 2.2.25 tomcat 7.0.42 jdk 1.7.0 1.安装apache 我这里是直接yum安装的,如果你们要编译安装也不是不行. 代码如下 ...2016-01-28
- 明明我的手机配置那么高(都八核了)为什么玩游戏还会卡?对安卓手机来说玩游戏卡顿的原因一般有两种;性能不足导致的卡顿以及CPU发热降频导致的卡顿,详情我们来看看吧...2017-07-06