Spring Boot学习篇(十三)

news2024/9/23 21:28:07

Spring Boot学习篇(十三)

shiro安全框架使用篇(五)

1 准备工作

1.1 在SysUserMapper.xml中书写自定义标签

<select id="findRoles" resultType="string">
     select name from sys_role where id = (select roleid from sys_user_role where userid = (SELECT id FROM `sys_user` where username = #{username}))
</select>
<select id="findPerms" resultType="string">
    select name from sys_permission where id in
    (select perid from sys_role_permission where roleid in
    (select roleid from sys_user_role where userid in
    (SELECT id FROM `sys_user` where username =#{username})))
</select>

1.2 SysUserMapper接口书写自定义标签所对应的方法

//根据用户名查询角色
List<String> findRoles(String username);
//根据用户名查询权限
List<String> findPerms(String username);

1.3 login.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2 th:if="${msg!=null}" th:text="${msg}"></h2>
    <form action="/users/login" method="post">
        <!--需要与控制器保持一致-->
        用户名:<input type="text" name="yhm">
        密码:<input type="password" name="mm">
        记住我: <input type="checkbox" name="jzw">
        <button>登录</button>
    </form>
</body>
</html>

1.4 index.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   主页
   <a href="/zhuxiao">注销</a>
   <a href="/songs/find">查询商品</a>
   <a href="/songs/update">更改商品</a>
   <a href="/songs/insert">添加商品</a>
   <a href="/songs/delete">删除商品</a>
</body>
</html>

1.5 qx.html界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <h1>你没有该访问权限</h1>
   <a href="/index.html">点击进入主页</a>
</body>
</html>

1.6 SongsController类

package com.zlz.controller;

import com.zlz.entity.Songs;
import com.zlz.service.ISongsService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zlz
 * @since 2023-02-04
 */
//跨域的问题  1.协议不同 2.地址不同 3.端口不同 三者满足其一,就是跨域
//(origins = "*") origins仅允许指定域名访问 (origins = "http://127.0.0.1:8848")
@CrossOrigin
@Controller
@RequestMapping("/songs")
public class SongsController {
    @Autowired
    ISongsService iSongsService;
    @RequestMapping("select")
    @ResponseBody
    public List<Songs> s(){
        return iSongsService.list();
    }
   @RequestMapping("find")
   public String a(){
       System.out.println("查询数据");
       return "index";
   }
   @RequestMapping("delete")
   //
   //角色,需要自定义异常
   @RequiresRoles(value = {"经理","组长"},logical = Logical.OR)
   //判断是否具有权限的
//   @RequiresPermissions()
   public String b(){
       System.out.println("删除数据");
       return "index";
   }
    @RequiresUser
    @RequestMapping("update")
    public String c(){
        System.out.println("修改数据");
        return "index";
    }
    @RequestMapping("insert")
    public String d(){
        System.out.println("添加数据");
        return "index";
    }

}

2.操作授权(全满足)

2.1 在MySqlRealm类里面(继承了AuthorizingRealm抽象类)书写授权方法的内容

@Resource
SysUserMapper sysUserMapper;
//授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection p) {
    //注意看方法的返回值,一般是返回方法返回值类型所对应的实现类(Simple开头+方法返回值类型)
    //①得到当前登录的用户名
    String yhm =(String)p.getPrimaryPrincipal();
    //②查询到该用户的角色和权限
    List<String> roles = sysUserMapper.findRoles(yhm);
    List<String> perms = sysUserMapper.findPerms(yhm);
    //③ 控制台打印 方便查看效果
    System.out.println(yhm+"具有权限"+roles);
    System.out.println(yhm+"具有角色"+perms);
    //④授权并返回
    SimpleAuthorizationInfo sm=new SimpleAuthorizationInfo();
    sm.addRoles(roles);
    sm.addStringPermissions(perms);
    return sm;
}

2.2 在ShiroConfig类的factoryBean方法中配置控制器过滤

//默认是roles[角色名1,角色名2...角色名n],因为底层用的是hasAllRoles方法,因此是必须含有全部权限
//下面代码表示经理和组长的权限都要满足才可以进行删除
map.put("/songs/delete","user,roles[经理,组长]");

2.3 在ShiroConfig类中的factoryBean方法配置没有权限时的跳转地址

//检测到没有权限时的地址
sb.setUnauthorizedUrl("/qx.html");

2.4 设置没有权限时跳转的页面(templates目录下)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <h1>你没有该访问权限</h1>
   <a href="/index.html">点击进入主页</a>
</body>
</html>

2.5 测试

2.5.1 使用admin用户(具有经理权限)登录后并点击删除商品进入如下界面

在这里插入图片描述

2.5.2 使用aaa用户(具有组长权限)登录后并点击删除商品进入如下界面

在这里插入图片描述

3.操作授权(满足其中之一)

3.1 自定义角色过滤器类MyRolesFilter(继承RolesAuthorizationFilter类)

package com.zlz.filter;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Set;

/**
 * 自定义角色过滤器
 */
public class MyRolesFilter extends RolesAuthorizationFilter {
    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        String[] rolesArray = (String[])mappedValue;
        if (rolesArray != null && rolesArray.length != 0) {
            Set<String> roles = CollectionUtils.asSet(rolesArray);
            boolean b=false;
            for (String role : roles) {
                //满足其中之一就返回,hasRole满足条件就为true,
                if(subject.hasRole(role)){
                    b=true;
                    break;
                }
            }
            return b;
        } else {
            return true;
        }
    }
}

3.2 核心代码(在ShiroConfig类中factoryBean方法中)

/**
* 自定义过滤器 换个名字好点 sb是ShiroFilterFactoryBean类型的对象
*/
Map<String, Filter> myFilter=new HashMap<>();
myFilter.put("myroles",new MyRolesFilter());
sb.setFilters(myFilter);
//设置删除商品需要经理或者组长其一的权限
map.put("/songs/delete","user,myroles[经理,组长]");

3.3 完整的ShiroConfig类代码

package com.zlz.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.zlz.filter.MyRolesFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    //shiro标签库
    @Bean
    public ShiroDialect sd(){
        return new ShiroDialect();
    }
    //配置安全管理器 shiro核心配置类
    @Bean
    public DefaultWebSecurityManager securityManager(){
          DefaultWebSecurityManager dms=new DefaultWebSecurityManager();
          //设置域(查询数据库dao类) 查哪里的数据库设置
          dms.setRealm(realm());
        //设置会话管理器
        dms.setSessionManager(new DefaultWebSessionManager());
        //设置记住我管理器
        dms.setRememberMeManager(ck());
        return dms;
    }
    @Bean
    public Realm realm(){
        MysqlRealm r=new MysqlRealm();
        //设置密码加密 登录是加密比对
        HashedCredentialsMatcher hsm = new HashedCredentialsMatcher();
        hsm.setHashAlgorithmName("sha-256");
        hsm.setHashIterations(100);
        r.setCredentialsMatcher(hsm);
        return r;
    }
    //shiro过滤器(核心)
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean factoryBean(){
        ShiroFilterFactoryBean sb=new ShiroFilterFactoryBean();
        //设置安全管理器
        sb.setSecurityManager(securityManager());
        /*
          基本设置

         */
        //检测到没有登录的地址
        sb.setLoginUrl("/login.html");
        //检测到没有权限时的地址(这里是一种设置没有权限时候跳转的地址)
        sb.setUnauthorizedUrl("/qx.html");

        /**
         * 自定义过滤器 换个名字好点 sb是ShiroFilterFactoryBean类型的对象
           是通过map集合设置进去的
         */
        Map<String, Filter> myFilter=new HashMap<>();
        myFilter.put("myroles",new MyRolesFilter());
        sb.setFilters(myFilter);

        //控制器过滤设置 拦截有顺序//
        /**
         * anon 允许匿名访问  无需登录
         * user 需要登录后才能访问
         * roles 需要具有所有的角色
         * perms 需要具有所有的权限
         * logout 注销过滤器
         * authc 不包含记住我 需要登录
         */
        Map<String,String> map=new LinkedHashMap<>();
        map.put("/*.html", "anon");
        //注销流程 自己清空session
        map.put("/zhuxiao", "logout");
        map.put("/songs/find","anon");
        //myroles就是和之前定义的key值保持一致
        map.put("/songs/delete","user,myroles[经理,组长]");
        //放行写上面 拦截写下面
        sb.setFilterChainDefinitionMap (map);
        return sb;
    }
    @Bean
    public CookieRememberMeManager ck(){
        CookieRememberMeManager c=new CookieRememberMeManager();
        SimpleCookie sc=new SimpleCookie();
        sc.setHttpOnly(true);//防止js读取cookie
        sc.setMaxAge(60);//设置cookie时长
        sc.setName("zlz");
        c.setCookie(sc);
        return c;
    }
}

3.3 测试

3.3.1 组长权限(用户名为aaa)
a 点击删除按钮后跳转的界面

在这里插入图片描述

b 点击删除按钮后的idea控制台界面

在这里插入图片描述

3.3.2 管理员权限(用户名为admin)
a 点击删除按钮后跳转的界面

在这里插入图片描述

b 点击删除按钮后的idea控制台界面

在这里插入图片描述

4 设置注销后跳转的地址

4.1 核心代码

//Map<String, Filter> myFilter=new HashMap<>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/index.html");//修改注销后的跳转地址,如果没有设置默认跳转的是login.html界面
 myFilter.put("logout",logoutFilter);

4.2 运行截图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/342640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Matlab论文插图绘制模板第77期—对数刻度横向柱状图

在之前的文章中&#xff0c;分享了Matlab对数刻度柱状图的绘制模板&#xff1a; 进一步&#xff0c;再来看一下对数刻度横向柱状图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;Matlab论文插图绘制模板系列&#xff0c;旨在降低大家使用Matlab进行科研绘…

[WTL/ATL]_[初级]_[TreeView控件如何显示ToolTip]

场景 在开发界面程序时&#xff0c;CTreeViewCtrl(它实际内部封装的就是Win32的TreeView控件)一般会用来作为选择某些类型的树形菜单&#xff0c;点击某项的时候&#xff0c;右边能显示某些对应的数据。当这个控件的宽度固定时&#xff0c;有时候每行的文本项可能由于过长从而…

【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(双向LSTM,附完整代码和数据集)

写在前面&#xff1a; 首先感谢兄弟们的关注和订阅&#xff0c;让我有创作的动力&#xff0c;在创作过程我会尽最大能力&#xff0c;保证作品的质量&#xff0c;如果有问题&#xff0c;可以私信我&#xff0c;让我们携手共进&#xff0c;共创辉煌。 在https://blog.csdn.net/A…

【CSS】元素居中总结-水平居中、垂直居中、水平垂直居中

【CSS】元素居中一、 水平居中1.行内元素水平居中&#xff08;1&#xff09;text-align2.块级元素水平居中2.1 margin&#xff08;1&#xff09;margin2.2布局&#xff08;1&#xff09;flex justify-content&#xff08;推荐&#xff09;&#xff08;2&#xff09; flexmargin…

张驰咨询:关于六西格玛,有一些常见的疑惑!

​ 很多想要学习六西格玛的学员&#xff0c;经常会有这些困惑&#xff1a; 以前没有接触过六西格玛&#xff0c;需要什么基础吗&#xff1f;自学还是培训&#xff1f;哪些行业会用到六西格玛呢&#xff1f;学习六西格玛对以后的工作有哪些帮助&#xff1f;如何选择六西格玛培…

STM32配置读取双路24位模数转换(24bit ADC)芯片CS1238数据

STM32配置读取双路24位模数转换&#xff08;24bit ADC&#xff09;芯片CS1238数据 CS1238是一款国产双路24位ADC芯片&#xff0c;与CS1238对应的单路24位ADC芯片是CS1237&#xff0c;功能上相当于HX711和TM7711的组合。其功能如下所示&#xff1a; 市面上的模块&#xff1a; …

股票买卖接口怎么来的?

现在股票买卖接口主要是在线上研发&#xff0c;有专业的开发团队进行源码开发和完善&#xff0c;但是&#xff0c;常常会在开发过程中出现问题&#xff0c;也就是遇到一些特殊的情况需要及时处理&#xff0c;那么股票买卖接口怎么开发实现出来的&#xff1f;一、股票买卖接口开…

案例分享| 助力数字化转型:广州期货交易所全栈信创项目管理平台上线

广州期货交易所项目管理平台基于易趋&#xff08;easytrack&#xff09;进行实施&#xff0c;通过近半年的开发及试运行&#xff0c;现已成功交付上线、推广使用&#xff0c;取得了良好的应用效果。1. 关于广州期货交易所&#xff08;以下简称广期所&#xff09;广期所于2021年…

MySQL8.0安装教程

文章目录1.官网下载MySQL2.下载完记住解压的地址&#xff08;一会用到&#xff09;3.进入刚刚解压的文件夹下&#xff0c;创建data和my.ini在根目录下创建一个txt文件&#xff0c;名字叫my&#xff0c;文件后缀为ini&#xff0c;之后复制下面这个代码放在my.ini文件下&#xff…

华为手表开发:WATCH 3 Pro(4)创建项目 + 首页新建按钮,修改初始文本

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;4&#xff09;创建项目 首页新建按钮&#xff0c;修改初始文本初环境与设备创建项目创建项目入口配置项目认识目录结构修改首页初始文本文件名&#xff1a;index.hml新建按钮 “ 按钮 ”index.hml初 鸿蒙可穿戴开发 希望能写…

直播预告 | 对谈谷歌云 DORA 布道师:聊聊最关键的四个 DevOps 表现指标

本期分享 DORA 的全称是 DevOps Research and Assessment&#xff0c;是一个致力于 DevOps 调研与研究的组织&#xff0c;2018 年加入 Google Cloud。自 2014 年起&#xff0c;DORA 每年会发布一份行业报告&#xff0c;基于对数千名从业者的调研&#xff0c;分析高效能团队与低…

联想K14电脑开机全屏变成绿色无法使用怎么U盘重装系统?

联想K14电脑开机全屏变成绿色无法使用怎么U盘重装系统&#xff1f;最近有用户使用联想K14电脑的时候&#xff0c;开机后桌面就变成了绿色的背景显示&#xff0c;无法进行任何的操作。而且通过强制重启之后还是会出现这个问题&#xff0c;那么这个情况如何去进行系统重装呢&…

PMP证书要怎么考,含金量怎么样?

很多朋友在对PMP不是了解的时候&#xff0c;会有些犹豫&#xff0c;PMP证书到底值不值得考。考下来有用吗&#xff1f; PMP证书当然有用&#xff0c;要含金量有含金量&#xff0c;要专业知识有专业知识&#xff0c;不过要是考了不用&#xff0c;久而久之忘了学习的内容&#x…

怿星科技校招礼盒:我想开了

校招礼盒大揭秘为了帮助2023届新同学快速了解怿星文化增强认同感经过1个多月的精心准备我们的校招大礼盒终于跟大家见面啦&#xff01;&#xff01;我们用了大量的公司IP形象-小怿通过各式各样的姿势和表情欢迎新同学的到来搭配着IP的蓝色色调传递出一种科幻与探索的感觉希望加…

计算机组成原理:1. 计算机系统概论

更好的阅读体验\huge{\color{red}{更好的阅读体验}}更好的阅读体验 文章目录1.1 计算机系统简介1.1.1 计算机软硬件概念1.1.2 计算机的层次1.1.3计算机组成和计算机体系结构1.2 计算机的基本组成1.2.1 冯诺伊曼计算机的特点1.2.2 计算机的硬件框图1.2.3 计算机的工作步骤1.3 计…

问卷调查会遇到哪些问题?怎么解决?

提到问卷调查我们并不陌生&#xff0c;它经常被用作调查市场、观察某类群体的行为特征等多种调查中。通过问卷调查得出的数据能够非常真实反映出是市场的现状和变化趋势&#xff0c;所以大家经常使用这个方法进行调查研究。不过&#xff0c;很多人在进行问卷调查的时候也会遇到…

JAVA八股、JAVA面经

还有三天面一个JAVA软件开发岗&#xff0c;之前完全没学过JAVA&#xff0c;整理一些面经...... 大佬整理的&#xff1a;Java面试必备八股文_-半度的博客-CSDN博客 另JAVA学习资料&#xff1a;Java | CS-Notes Java 基础Java 容器Java 并发Java 虚拟机Java IO目录 int和Inte…

电商新趋势来临!?解析Dtop 环球嘉年华电商是否值得加入!

近年来,电商平台的发展瞬息万变,加上疫情的推波助澜,让全球的电子商务来到前所未有的光景,营业销售额直达颠覆性的增长。 许多商家也因此纷涌而入,谋划分得电子商务的一杯羹。随着参与成为电商的商家日益剧增,商家们想从中谋利也不是件易事。再加上市场不断洗牌的形势下,传统电…

楔形文字的起源全2课-北京大学拱玉书 笔记

楔形文字的起源全2课-北京大学拱玉书 说明&#xff1a;以下图片素材均出自视频 【楔形文字的文源】 《吉尔伽美什史诗》记载的楔形文字起源&#xff1a; 学术界对楔形文字起源的总结&#xff1a; 【关于文字的演化理论发展史】 威廉.瓦尔伯顿提出文字“叙事图画”演变说…

浅谈 RBAC 权限模型

写作背景 工作两年半了&#xff0c;笔者一直在做 To B 的产品&#xff0c;像是后端管理系统、Saas 系统都有接触过&#xff0c;它们都有一个共同点&#xff1a;权限管理。我每天都在接触但只是从前端开发这个角色去理解&#xff0c;我对整个业务流程其实是比较模糊的&#xff…