微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于SpringBoot2的Shiro最简配置操作(两个文件)

这篇文章主要介绍了基于SpringBoot2的Shiro最简配置操作(两个文件),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

基础环境:依赖

org.springframework.bootspring-boot-starter-parent2.2.1.RELEASE

org.apache.shiroshiro-spring-boot-starter1.4.0

如果不是前后端分离,要实现页面级的权限控制,则加入以下依赖就可以使用shiro的权限标签了(记得在html头部加上相应约束:

): com.github.theborakompanionithymeleaf-extras-shiro2.0.0

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 userRoles = userRoleService.list(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userInfo.getId())) .stream() .map(SysUserRole::getRoleId) .collect(Collectors.toSet()); //角色所有权限 Set 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().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 filterChainDeFinitionMap = new LinkedHashMap(); // 允许匿名用户访问首页 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 filters = new LinkedHashMap(); // 定制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时出现空值导致匹配失败。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程之家。如有错误或未考虑完全的地方,望不吝赐教。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐