欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

【shiro基础】springboot整合shiro

时间:2023-07-08
目录

基础知识

shiro 功能架构 依赖引入自定义Realm域,完成认证及授权过程

定义登录接口,触发subject.login(token)自定义Realm域,用于完成认证及授权过程。 shiro 配置类,配置FactoryBean及web安全管理器数据库设计

用户表资源权限表用户权限表 附 基础知识 shiro 功能


Authentication:认证;
Authorization:授权;
Session Management:会话管理,shiro拥有自己的session管理机制;
Cryptography:加密解密,管理如密码等数据;
Caching:缓存支持;
Concurrency:shiro 并发验证;
Testing:提供测试支持;
Run As:身份授权访问;
Remember Me:记住我;

架构

这部分资料比较多,不再啰嗦。

Subject:主体,即 “用户”;
SecurityManager:shiro安全管理器,管理 Subject、负责进行认证和授权、及会话、缓存的管理。
Authenticator:认证;
Authorizer:授权;
Realm:安全域,可以有 1 个或多个 Realm;;
SessionManager:绘画管理器;
Cryptography:加密解密模块。

依赖引入

完整项目引入包括:

<?xml version="1.0" encoding="UTF-8"?> 4.0.0 org.example springboot-shiro-demo 1.0-SNAPSHOT 8 8 org.springframework.boot spring-boot-starter-parent 2.3.6.RELEASE pom import org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-autoconfigure org.springframework.boot spring-boot-starter-web com.baomidou mybatis-plus-boot-starter 3.5.0 mysql mysql-connector-java 8.0.16 org.projectlombok lombok 1.18.10 org.apache.shiro shiro-spring-boot-starter 1.8.0

自定义Realm域,完成认证及授权过程 定义登录接口,触发subject.login(token)

这一步主要完成认证数据(用户名、密码)的获取及token的创建,然后提交shiro进行认证。

@RequestMapping("/sublogin") public String subLogin(String userName,String password) { Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken(userName,password); try { subject.login(token); subject = SecurityUtils.getSubject(); // 设置shiro session (非必须) Session shiroSession = subject.getSession(); shiroSession.setAttribute("user",subject.getPrincipal()); return "OK:"+userName; }catch (UnknownAccountException e) { return "用户不存在"; } catch (IncorrectCredentialsException e){ return "密码不正确"; }catch (AuthenticationException e) { return "登录失败"; } }

自定义Realm域,用于完成认证及授权过程。

此步骤主要完成认证、授权两个过程,并对其中认证中的密码匹配器进行了重写(MD5).
认证: 主要用于构建认证对象(从数据库读取),用于提供给shiro进行认证操作。
授权: 主要用于读取(数据库)授权信息,提供给shiro,以完成授权检查。

package cn.com.demo.shiro.config;import cn.com.demo.shiro.entity.TShiroUser;import cn.com.demo.shiro.service.UserService;import cn.com.demo.shiro.util.MD5;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.authc.credential.CredentialsMatcher;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.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;@Componentpublic class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); // 拿到当前用户 Subject subject = SecurityUtils.getSubject(); TShiroUser user = (TShiroUser) subject.getPrincipal(); // 设置权限 simpleAuthorizationInfo.setStringPermissions(userService.getUserPermission(user.getId())); return simpleAuthorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; if(StringUtils.isEmpty(token.getUsername())){ // 用户名为空 return null; } TShiroUser user = userService.getUserByUserName(token.getUsername()); if(user == null) { return null; } return new SimpleAuthenticationInfo(user,user.getPassword(),""); } @Override public CredentialsMatcher getCredentialsMatcher() { return new CredentialsMatcher() { @Override public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) { UsernamePasswordToken utoken = (UsernamePasswordToken) authenticationToken; //获得用户输入的密码 String formPassword = new String(utoken.getPassword()); //获得数据库中的密码 String dbPassword = (String) authenticationInfo.getCredentials(); try { formPassword = MD5.encrypt(formPassword); return dbPassword.equalsIgnoreCase(formPassword); } catch (Exception e) { e.printStackTrace(); return false; } } }; }}

shiro 配置类,配置FactoryBean及web安全管理器

FactoryBean: 用于构建shiro环境及配置,配置各类资源权限,鉴权信息(如登录、授权失败等)、安全管理器等配置
web安全管理器: 用于向shiro提供自定义Realm域。
此过程中,完成Factory到Realm的关联。

package cn.com.demo.shiro.config;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;import cn.com.demo.shiro.entity.TShiroResPermission;import cn.com.demo.shiro.service.UserService;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.linkedHashMap;import java.util.List;import java.util.Map;@Configurationpublic class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Autowired DefaultWebSecurityManager defaultWebSecurityManager, @Autowired UserService userService){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); // shiro 内置过滤器 org.apache.shiro.web.filter.mgt.DefaultFilter Map map = new linkedHashMap<>(); // 登录相关免认证接口 map.put("/auth @Bean public DefaultWebSecurityManager defaultWebSecurityManager(@Autowired UserRealm userRealm){ DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm(userRealm); return defaultWebSecurityManager; }}

数据库设计 用户表

CREATE TABLE `t_shiro_user` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名', `password` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

资源权限表

可对应实际生产的角色、菜单、按钮等跟权限有关的表

CREATE TABLE `t_shiro_res_permission` ( `id` int NOT NULL AUTO_INCREMENT, `res_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '资源(如url)', `permission_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '权限代码', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

用户权限表

对应用户权限信息;RBAC 权限方案中,还需要用户角色的参与,此表只用于简单表述用户的权限。

CREATE TABLE `t_shiro_user_permission` ( `id` int NOT NULL AUTO_INCREMENT, `user_id` int NOT NULL COMMENT '用户id', `permission_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '权限代码', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

完整源代码

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。