栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

基础环境:依赖


 org.springframework.boot
 spring-boot-starter-parent
 2.2.1.RELEASE
  

 org.apache.shiro
 shiro-spring-boot-starter
 1.4.0

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


):

 com.github.theborakompanioni
 thymeleaf-extras-shiro
 2.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;
 

@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(), 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;
 

@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时出现空值导致匹配失败。

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/129266.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号