Springboot2(23)轻松整合shiro(带验证码)

2023-11-16

源码地址

springboot2教程系列

Shiro配置

1.Spring集成Shiro一般通过xml配置,SpringBoot集成Shiro一般通过java代码配合@Configuration和@Bean配置。

2.Shiro的核心通过过滤器Filter实现。Shiro中的Filter是通过URL规则来进行过滤和权限校验,所以我们需要定义一系列关于URL的规则和访问权限。

3.SpringBoot集成Shiro,我们需要写的主要是两个类,ShiroConfiguration类,还有继承了AuthorizingRealm的Realm类。

  • ShiroConfiguration类,用来配置Shiro,注入各种Bean。包括过滤器(shiroFilter)、安全事务管理器(SecurityManager)、密码凭证(CredentialsMatcher)、aop注解支持(authorizationAttributeSourceAdvisor)等等
  • Realm类,包括登陆认证(doGetAuthenticationInfo)、授权认证(doGetAuthorizationInfo)

引入依赖

   <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
		<shiro.version>1.4.0</shiro.version>
		<commons.lang.version>2.6</commons.lang.version>
		<kaptcha.version>0.0.9</kaptcha.version>
	</properties>


	<dependencies>

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>${commons.lang.version}</version>
		</dependency>

		<dependency>
			<groupId>com.github.axet</groupId>
			<artifactId>kaptcha</artifactId>
			<version>${kaptcha.version}</version>
		</dependency>
		
    </dependencies>

编写ShiroConfiguration类

/**
 * Shiro的配置文件
 */
@Configuration
public class ShiroConfig {

    /**
     * Session会话管理器,session交给shiro管理
     */
    @Bean
    public DefaultWebSessionManager sessionManager(@Value("${myframe.sessionTimeout:3600}") long globalSessionTimeout){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //是否开启会话验证器,默认是开启的
        sessionManager.setSessionValidationSchedulerEnabled(true);
        //禁止URL地标后面添加JSESSIONID
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        //设置全局会话超时时间
        sessionManager.setGlobalSessionTimeout(globalSessionTimeout * 1000);
        sessionManager.setSessionValidationInterval(globalSessionTimeout * 1000);
        return sessionManager;
    }


    /**
     * 安全管理器
     * @param userRealm
     * @param sessionManager
     * @return
     */
    @Bean("securityManager")
    public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        securityManager.setRememberMeManager(null);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }


    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl("/login.html");
        shiroFilter.setUnauthorizedUrl("/");

        Map<String, String> filterMap = new LinkedHashMap<>();

        filterMap.put("/public/**", "anon");
        filterMap.put("/login.html", "anon");
        filterMap.put("/sys/login", "anon");
        filterMap.put("/captcha.jpg", "anon");
        filterMap.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterMap);

        return shiroFilter;
    }

    /**
     * Shiro生命周期处理器,保证实现了Shiro内部lifecycle函数的bean执行
     * @return
     */
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     *  启用shrio授权注解拦截方式,AOP式方法级权限检查
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    /**
     * 加入注解的使用,不加入这个注解不生效 使用shiro框架提供的切面类,用于创建代理对象
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}

过滤器Filter实现

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean shiroFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
        //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
        registration.addInitParameter("targetFilterLifecycle", "true");
        registration.setOrder(Integer.MAX_VALUE - 1);
        registration.setEnabled(true);
        registration.addUrlPatterns("/*");
        return registration;
    }

}

Realm类实现

/**
 * 认证
 */
@Component
public class UserRealm extends AuthorizingRealm {
    @Resource
    private SysUserDao sysUserDao;
    
    /**
     * 授权(验证权限时调用)
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
		Long userId = user.getUserId();
        //用户权限列表
		Set<String> permsSet = new HashSet<>();
		String perms = sysUserDao.queryAllPerms(userId);
		permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}

	/**
	 * 认证(登录时调用)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
		//查询用户信息
		SysUserEntity user = sysUserDao.selectOne(token.getUsername());
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		return info;
	}

}

登录实现类

**
 * 登录相关
 */
@Controller
public class SysLoginController {
	@Autowired
	private Producer producer;

	/**
	 * 生成验证码
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("captcha.jpg")
	public void captcha(HttpServletResponse response)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存到shiro session
        ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
	}
	
	/**
	 * 登录
	 */
	@ResponseBody
	@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
	public R login(String username, String password, String captcha) throws IllegalAccessException {
		String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
		if(!captcha.equalsIgnoreCase(kaptcha)){
			return R.error("验证码不正确");
		}
		try{
			Subject subject = ShiroUtils.getSubject();
			UsernamePasswordToken token = new UsernamePasswordToken(username, password);
			subject.login(token);
		}catch (UnknownAccountException e) {
			return R.error(e.getMessage());
		}catch (LockedAccountException e) {
			return R.error("账号已被锁定,请联系管理员");
		} catch (IncorrectCredentialsException e) {
			return R.error("账号或密码不正确");
		}catch (AuthenticationException e) {
			return R.error("账户验证失败");
		}
		return R.ok();
	}
	
	/**
	 * 退出
	 */
	@RequestMapping(value = "logout", method = RequestMethod.GET)
	public String logout() {
		ShiroUtils.logout();
		return "redirect:login.html";
	}
	
}

权限测试类

@RestController
public class PermController {

    @RequestMapping("/sysRead")
    @RequiresPermissions("sys:read")
    public String sysRead(){
        return "you can sysRead";
    }

    @RequiresPermissions("sys:write")
    @RequestMapping("/sysWrite")
    public String sysWrite(){
        return "you can sysWrite";
    }

    @RequiresPermissions("sys:delete")
    @RequestMapping("/sysDelete")
    public String sysDel(){
        return "you can sysDelete";
    }
}

每次访问带有@RequiresPermissions()方法时,都会进入UserRealm类的AuthorizationInfo()授权方法

另外subject.hasRole(“admin”) 或 subject.isPermitted(“admin”) 也会调用AuthorizationInfo()授权方法

登录测试(用户密码tom/123456)
在这里插入图片描述

权限测试
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot2(23)轻松整合shiro(带验证码) 的相关文章

  • Apache Shiro(三)——Spring Boot 与 Shiro的 整合

    在了解了Apache Shiro的架构 认证 授权之后 我们来看一下Shiro与Web的整合 下面以Spring Boot为例 介绍一下Spring Boot 与 Shiro的 整合 一 创建一个Spring Boot项目 可以使用IDEA
  • Springboot2(27)集成netty实现反向代理(内网穿透)

    源码地址 springboot2教程系列 其它netty文件有博客 Springboot2 24 集成netty实现http服务 类似SpingMvc的contoller层实现 Springboot2 25 集成netty实现文件传输 Sp
  • Ajax 和 PHP 实现验证码的实时验证

    我的个人博客 逐步前行STEP PHP的图像处理功能强大 做一张验证码图片也是非常简单的 但是 在实现实时验证时 确遇到了一个难题 我用nat123对我的电脑上的网站进行端口映射 实现了在外网访问 本来是采用cookie的方式用js对验证码
  • shiro框架---通过系统介绍shiro框架中的实现逻辑

    接上一篇文章关于shiro框架的简单介绍及用户表的建立维护 项目已分享到GitHub上 如果需要的可以看下 springboot shiro项目Git下载地址 本篇主要通过一个已经实现用户登录和权限验证的系统 结合sql 展示一下我的实现
  • SpringBoot基本操作(七)——SpringBoot整合Shiro权限管理(完整demo+界面)

    SpringBoot2 0笔记 一 SpringBoot基本操作 环境搭建及项目创建 有demo 二 SpringBoot基本操作 使用IDEA打war包发布及测试 三 SpringBoot基本操作 SpringBoot整合SpringDa
  • SpringBoot 整合 Shiro 常见配置

    目录 一 Shiro 基础解释 过滤器 AOP 实现安全认证权限管理逻辑 了解 Shiro 的组织架构 二 SpringBoot 整合 Shiro 1 在项目中使用 Shiro 需要配置的地方 2 代码示例 引入依赖 请求接口 自定义 Re
  • shiro SecurityManager简介说明

    转自 shiro SecurityManager简介说明 下文笔者讲述Shiro SecurityManager的相关简介说明 如下所示 SecurityManager是Shiro框架的核心 典型的Facade模式 Shiro通过Secur
  • 原生JS局部刷新

    目录 使用XMLHttpRequest对象进行异步请求 2 使用fetch API进行异步请求 3 使用事件监听器进行局部刷新 4 servlet实现img验证码局部刷新 依赖jar包 Servlet login jsp 在原生JS中 可以
  • 源码分析shiro认证授权流程

    1 shiro介绍 Apache Shiro是一个强大易用的Java安全框架 提供了认证 授权 加密和会话管理等功能 认证 用户身份识别 常被称为用户 登录 授权 访问控制 密码加密 保护或隐藏数据防止被偷窥 会话管理 每用户相关的时间敏感
  • shiro使用自定义realm实现数据认证

    自定义realm实现数据认证 在开发中 有时会与一些nosql或者其他地方保存的数据进行认证 这时候 shiro定义的那些realm类可能不能满足实际的功能需求 这时候我们可以通过自定义一个realm来沟通这些数据 实现认证和权限控制 首先
  • shiro-session-ehcache配置

    首先准备好jar包 shiro的主要四个 ehcache shiro xml 配置 首先securityManager配置 sessionManager配置
  • 将 Shiro 的 PasswordMatcher 与自定义领域结合使用

    我使用 Apache Shiro 和自定义 JDBC 领域来从数据库中检索用户的盐 密码 哈希算法名称和哈希迭代次数 这些数据都存储为单独的列 问题是我不确定在使用 PasswordMatcher 验证用户密码与数据库中存储的密码是否匹配时
  • Shiro/Stormpath 通过 REST

    我是新来的士郎 我们正在尝试将 Shiro 与 Stormpath 一起使用 我一直在尝试剖析这些例子 以找出我想做的解决方案 但到目前为止我还没有成功 目前 我只是尝试创建 REST 服务来执行我想要的操作 稍后我将绑定一个真正的客户端
  • 如何将已通过身份验证的用户从登录页面重定向到主页

    我正在使用 Apache Shiro 开发 JSF 应用程序 我使用 Shiro 验证用户并将她重定向到主页 这没有问题 身份验证后 当我尝试访问登录页面时 它不会将我重定向到主页 即使已经有登录的用户 我也可以再次登录 我正在做程序化登录
  • 定制/扩展Spring对shiro的@Async支持

    我正在使用Spring的 EnableAsync异步执行方法的功能 为了安全起见 我使用 Apache Shiro 在异步执行的代码中 我需要访问附加到触发异步调用的线程的 Shiro 主题 Shiro 支持通过将主题与主题相关联来在不同线
  • Jetty maven插件无法热重新部署shiro过滤器

    我不确定这是jetty的问题还是shiro的问题 但我正在尝试使用Jetty Maven插件进行开发 我想要的关键功能之一是Jetty在文件更改时的热重新部署 然而 当 jetty 尝试重新加载应用程序时 Shiro 抛出以下异常 我不确定
  • Shiro 与 SpringSecurity [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我目前正在评估基于Java的安全框架 我是Spring 3 0用户 因此SpringSecurity似乎是正确的选择 但Spring安全性似乎过
  • 配置 shiro.ini 以进行 JDBC 连接

    作为我新的一年学习新技术计划的一部分 我开始尝试使用 Apache Shiro 安全框架 我设法让基本示例正常工作 该示例将用户名 密码和角色存储在 shiro ini 文件中 但是当我修改 shiro ini 文件以使用 JDBC 时 它
  • Spring Boot 2 中的 401 代替 403

    With 春季启动 https projects spring io spring boot 1 5 6 发布我能够发送 HTTP 状态代码401代替403如中所述如果请求未经身份验证的uri 如何让Spring Security响应未经授
  • 请确保至少一个领域可以验证这些令牌

    所以我把我的shiro设置为有两个Realms 用户名和密码领域 使用标准 UsernamePasswordToken 我还设置了一个自定义承载身份验证令牌 用于处理从用户传入的令牌 如果我只使用我的passwordValidatorRea

随机推荐

  • 上帝之眼Nmap(黑客工具)简介及命令大全

    目录 前言 一 Nmap简介 1 1 Nmap优点 1 2 Nmap四项基本功能 二 Nmap常用命令 2 1 主机发现 2 2 扫描技术 2 3 端口规格和扫描顺序 2 4 服务 版本探测 2 5 脚本扫描 2 6 操作系统检测 2 7
  • 95、Image Restoration with Mean-Reverting Stochastic Differential Equations

    简介 主页 https github com Algolzw image restoration sde 扩散模型终于在去噪 超分辨率等应用了 这是一种基于随机微分方程的通用图像恢复方法 关键结构包括均值还原SDE 该SDE将高质量图像转换
  • 机会转瞬即逝刷脸看准目标把握未来

    所有的企业家 不仅仅要考虑全球化让我受益 而是要让全球化变得更加普惠 让更多的人 更多的企业受益 鼓励并且帮助更多企业参与全球竞争 全球贸易 贸易战是为昨天而战或者为昨天的利益而战 我们今天要思考的 不是怎么去维护或者保护昨天 而是应该赢得
  • Java-获取时间戳、util.Date、sql.Date类的使用

    Java 获取时间戳 util Date sql Date类的使用 1 获取时间戳 获取系统当前时间 System类中的currentTimeMillis package com lmw time import org junit Test
  • 不定量表达法

    文章目录 1 some 一些 any 一些 most 大多数 every 每一个 all 所有的 2 both 两者都 either 两者之一 neither 两者都不 3 many 许多 much 许多 a lot of lots of
  • eclipse之 Type Hierachy:Viewing the type hierarchy

    1 Type Hierachy 继承关系层次图快捷键F4 2 show the type hierachy 子面板会根据选中的类显示对应的内容 show the supertype hierachy ctrl T 显示子类到父类的层次关系
  • Qt知识笔记(一)

    Qt知识笔记 一 Qt概述 Qt特点 Qt模块 Qt窗口类 坐标体系 相对坐标 垃圾回收机制 Qt概述 Qt是一个跨平台的 C 应用程序开发框架 具有短平快的优秀特质 投资少 周期短 见效快 效益高 几乎支持所有的平台 可用于桌面程序开发以
  • LVS负载均衡群集——LVS-NAT模式搭建和LVS-DR模式搭建

    目录 lvs工作模式 1 NAT模式 VS NAT 2 直接路由模式 VS DR 3 IP隧道模式 VS TUN LVS调度算法 LVS群集类型 1 负载均衡群集 LB 2 高可用群集 HA 3 高性能运输群集 HPC LVS NAT模式搭
  • element-ui + sortable.js 实现可拖拽表格

    element ui sortable js 实现可拖拽表格 先看效果 安装Sortablejs npm install sortablejs save demo
  • VC++ 源码实现通达信公式管理器2

    前面我们介绍了如何加载显示公式列表 本篇章介绍如何格式化显示公式内容 常用的CEdit或CRichEdit是不支持这种格式显示的 这里需要借助第三方控件SciLexer 没错 Notepad 就是使用的这个控件 它支持不同的文本内容支持不同
  • 基于多动作深度强化学习的柔性车间调度研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 文献来源 4 Python代码实现 1 概述 灵活作业车间调度问题 FJSP 在现代制造
  • 三维建模软件Cinema 4D 2024 mac(c4d2024)中文版特点

    Cinema 4D 2024 mac是一款专业的三维建模 动画和渲染软件 c4d2024 可以用于电影制作 广告设计 工业设计等领域 Cinema 4D 2024具有强大的建模工具 可以创建各种复杂的几何体 包括多边形网格 NURBS曲线和
  • arctan函数加上90°;arctan(a/b)与arctan(b/a)的关系

  • 隐藏设备管理器控件

    include
  • cocos学习笔记---Node 支持的事件类型

    Node 支持的事件类型主要有 export enum EventType 触摸事件 TOUCH START 0 当手指触点落在目标节点区域内时 TOUCH MOVE 0 当手指在屏幕上目标节点区域内移动时 TOUCH END 0 当手指在
  • 建立统计回归模型的基本步骤_基本回归模型

    建立统计回归模型的基本步骤 Linear Regression and Regression Trees 线性回归和回归树 by Satoru Hayasaka and Rosaria Silipo KNIME 由 悟早坂 和 罗萨丽娅Si
  • 如何在Latex中插入MATLAB代码

    最近在编写一篇文章时需要用到在latex中插入MATLAB代码 如果直接在文本中添加会使文章变得不美观 那么此时我们非常有必要了解一下如何在latex中插入优美的MATLAB代码 1 复制mcode std文件在latex目录里 通常情况下
  • MAC上安装LLVM+Clang

    MAC上安装LLVM Clang 折腾了一天的结果 感觉不把它写下来都对不住自己了 哭唧唧 参考资料 http clang llvm org get started html http blog csdn net shuaiby artic
  • vue中将base64流数据转成pdf文件可打印

    vue中将base64流数据转成pdf文件可打印 vue中将base64流数据转成pdf文件可打印 一 base编码转为pdf方法 二 打印方法 vue中将base64流数据转成pdf文件可打印 这次后端返参不是oss那边传回来的 而是传给
  • Springboot2(23)轻松整合shiro(带验证码)

    源码地址 springboot2教程系列 Shiro配置 1 Spring集成Shiro一般通过xml配置 SpringBoot集成Shiro一般通过java代码配合 Configuration和 Bean配置 2 Shiro的核心通过过滤