Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Springboot+shiro基于url身份认证和授权认证

Springboot+shiro基于url身份认证和授权认证

作者头像
bigsai
发布于 2019-09-24 03:52:16
发布于 2019-09-24 03:52:16
1.7K00
代码可运行
举报
文章被收录于专栏:bigsaibigsai
运行总次数:0
代码可运行

你还不会shiro吗?

  • 前奏
  • shiro核心配置文件(rolesFilter可选)。
  • 身份认证
  • 多表登录源如何操作?
  • 授权管理
  • 如何解决界面多角色/资源问题
  • 访问效果

权限管理在日常开发中很重要,所以硬着头皮也要啃下来。

实现功能:

  • 身份认证
  • 对不同页面进行url授权
  • 多表登录解决
  • 同一个页面多role访问

项目完整github地址 欢迎star

springboot一些学习整合完整地址

shiro的四大组件:

  • 身份认证(Authentication)-证明用户身份,通常叫做登陆(login)。
  • 授权(Authorization)-访问控制
  • 加密(Cryptography)-保护或隐藏数据
  • 会话管理(session management)每个用户时间敏感状态

三个核心组件:Subject, SecurityManager 和 Realms.

  • Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。   Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
  • SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
  • Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。   从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。
  • Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

Shiro内置过滤器,可以实现权限相关的拦截器

  • 常用的过滤器:
  • anon: 无需认证(登录)可以访问
  • authc: 必须认证才可以访问
  • user: 如果使用rememberMe的功能可以直接访问
  • perm: 该资源必须得到资源权限才可以访问
  • role: 该资源必须得到角色权限才可以访问

这里面只用到了身份认证和授权,权限认证只用到了一点点,shiro的原理是封装的过滤器,他能够在访问浏览器前能过自动完成一些内容。

shiro配置主要两部分——shiroconfig和自定义的Realm(继承AuthorizingRealm)。其中,shiroconfig是shiro的主要配置文件,而自定义的Realm主要是重写AuthorizingRealm的两个方法,分别是身份认证和授权认证调用数据库查询比对。而如果需要role访问则需要重写一个filter。

前奏

项目结构:

环境:

  • Springboot2
  • mybatis
  • shiro

新建表:

对应的bean:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.shiro.bean;

public class student {
    private String username;
    private String password;
    private String role;
    private String perm;
   //省略get set

mybatis简单查询:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.shiro.mapper;


import com.shiro.bean.student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface studentMapper {

    @Select("select  * from student where username=#{name}")
    student findByName(String name);
}

省略html和sql,详细可以到GitHub下载

页面目录,:

shiro核心配置文件(rolesFilter可选)。

UserRealm.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.shiro.config;

import com.shiro.bean.student;
import com.shiro.mapper.studentMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * 自定义Realm
 * @author bigsai
 *
 */
public class UserRealm extends AuthorizingRealm{

	@Autowired(required = false)
	private studentMapper studentMapper;
	private final Logger logger= LoggerFactory.getLogger(UserRealm.class);
	/**
	 * 执行授权逻辑
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		logger.info("执行逻辑授权");

		//给资源进行授权
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		//添加资源的授权字符串
		//到数据库查询当前登录用户的授权字符串
		//获取当前登录用户
		Subject subject = SecurityUtils.getSubject();
		student user = (student) subject.getPrincipal();
		student dbUser = studentMapper.findByName(user.getUsername());

		info.addRole(user.getRole());//添加role 和perms  role代表角色 perms代表操作,或者动作等。用于颗粒化权限管理
		info.addStringPermission(dbUser.getPerm());
		System.out.println("user:"+dbUser.getPerm());
		return info;
	}
	/**
	 * 执行认证逻辑
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		System.out.println("执行认证逻辑");
		//编写shiro判断逻辑,判断用户名和密码
		//1.判断用户名
		UsernamePasswordToken token = (UsernamePasswordToken)arg0;

		student user = studentMapper.findByName(token.getUsername());

		if(user==null){
			//用户名不存在
			return null;//shiro底层会抛出UnKnowAccountException
		}

		//2.判断密码
		return new SimpleAuthenticationInfo(user,user.getPassword(),"");
	}

}

rolesFilter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.shiro.config;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

// AuthorizationFilter抽象类事项了javax.servlet.Filter接口,它是个过滤器。
public class rolesFilter extends AuthorizationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception {
        Subject subject = getSubject(req, resp);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0) { //没有角色限制,有权限访问
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++) {
            if (subject.hasRole(rolesArray[i])) { //若当前用户是rolesArray中的任何一个,则有权限访问
                return true;
            }
        }
        return false;
    }
}

shiroConfig:shiro的主要配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.shiro.config;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
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 bigsai
 */
@Configuration
public class ShiroConfig {

    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);


        Map<String, Filter> filtersMap = new LinkedHashMap<>();
        filtersMap.put("rolesFilter",new rolesFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);//使用自定义fitter
        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perm: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map<String, String> filterMap = new LinkedHashMap<String, String>();



        filterMap.put("/login", "anon");//要将登陆的接口放出来,不然没权限访问登陆的接口
        filterMap.put("/getcontroller", "anon");
//
        //授权过滤器
        //注意:当前授权拦截后,shiro会自动跳转到未授权页面
        filterMap.put("/add", "perms[add]");
        filterMap.put("/update", "perms[update]");

//
        filterMap.put("/test1.html","rolesFilter[admin,user]");
        filterMap.put("/*", "authc");//authc即为认证登陆后即可访问

        
        //修改调整的登录页面
        shiroFilterFactoryBean.setLoginUrl("/index");
        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);


        return shiroFilterFactoryBean;
    }

    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    /**
     * 创建Realm
     */
    @Bean(name = "userRealm")
    public UserRealm getRealm() {
        return new UserRealm();
    }

}

身份认证

身份认证,就是登录校检。这是第一层过滤,并且当用户没有登录的时候,回退到没登陆的界面。在controller中,login的核心为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @RequestMapping("/login")
    public String login(String name, String password, Model model, HttpServletRequest request) {

        model.addAttribute("nama", "给个star");
        /**
         * 使用Shiro编写认证操作
         */
        //1.获取Subject
        Subject subject = SecurityUtils.getSubject();

        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(name, password);

        //3.执行登录方法
        try {
            subject.login(token);

            //登录成功
            //跳转
            return "redirect:/index2";
        } catch (UnknownAccountException e) {
            //e.printStackTrace();
            //登录失败:用户名不存在
            model.addAttribute("msg", "用户名不存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            //e.printStackTrace();
            //登录失败:密码错误
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }

releam中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		System.out.println("执行认证逻辑");
		//编写shiro判断逻辑,判断用户名和密码
		//1.判断用户名
		UsernamePasswordToken token = (UsernamePasswordToken)arg0;

		student user = studentMapper.findByName(token.getUsername());
		if(user==null){
			//用户名不存在
			return null;//shiro底层会抛出UnKnowAccountException
		}
		//2.判断密码
		return new SimpleAuthenticationInfo(user,user.getPassword(),"");
	}

而这只是表象的处理过程,而在releam(继承AuthorizingRealm)中需要充血doGetAuthenticationInfo()方法.

大致流程为:登录——>拿账号密码检验———>用着token的账号通过你的sql查询对象——>比对数据是否一致——>通过还是抛各种异常

而在shiroConfig中,基于url过滤时authc即可访问

多表登录源如何操作?

可能会遇到如下情况:教师端,学生端来自两张表,两个登录接口,我该如何使用shiro身份认证。对于这种问题,你可以配置多个releam,但是我觉得如果简单你可以在不同的登录接口下传递一个参数过来,这个参数就用session传递。因为,shiro的session和网页httprequest获得的session是同一个session

所以当你在login传递一个属性到releam中,可用 if else判断然后不同登录接口执行不同的查询方法即可。

授权管理

接上流程 是否登录——>是/否——(是)—>查询role/perm添加到subject——>过滤器校验该url需要权限——>可以访问/权限不足

shiro主要url可以根据角色(role)和资源(perm)的管理。对于role,可以是管理员,教师等,而perm,可能是一个动作,一个操作,等等。并且可能一个角色拥有多个role和perm。 同理,授权就是查询数据库的role或者perm字段添加到角色中。当然具体api不做介绍。 主要方法为上述:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		logger.info("执行逻辑授权");

		//给资源进行授权
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		//添加资源的授权字符串
		//到数据库查询当前登录用户的授权字符串
		//获取当前登录用户
		Subject subject = SecurityUtils.getSubject();
		student user = (student) subject.getPrincipal();
		student dbUser = studentMapper.findByName(user.getUsername());

		info.addRole(user.getRole());//添加role 和perms  role代表角色 perms代表操作,或者动作等。用于颗粒化权限管理
		info.addStringPermission(dbUser.getPerm());
		System.out.println("user:"+dbUser.getPerm());
		return info;
	}

而url中也是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 filterMap.put("/add", "perms[add]");
 filterMap.put("/update", "roles[admin]");

如何解决界面多角色/资源问题

常常遇到这种情况:一个接口/页面,有两个或者以上角色可以访问。然后再后台的过滤器配置总。shiro默认的配置是and而不是or。这就需要我们自己定义filter继承AuthorizationFilter从写对应方法。

以多角色访问为例子。从写上述就是文件rolesFilter。在使用的时候也要首先声明filter才能使用。

访问效果

在页面授权的

运行测试:访问其他接口都被返回到这个界面

登陆成功后,界面可以访问

有个小注意点:如果mybatis2.0版本回和spring-start-web有冲突。我用1.3.2版本没问题。 参考:百度百科 项目github地址

springboot一些学习整合完整地址

https://github.com/javasmall/SpringbootDemo/tree/master/springboot_shiro

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 bigsai 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
springboot整合shior初体验
​ Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
上分如喝水
2021/08/16
3410
springboot整合shior初体验
深入理解Shiro
​ Apache Shiro(发音为“shee-roh”,日语中“城堡”的意思)是一个功能强大且易于使用的 Java 安全框架,可执行身份验证、授权、加密和会话管理,可用于保护任何应用程序 -从命令行应用程序、移动应用程序到最大的 Web 和企业应用程序。
用户11097514
2024/05/30
2670
深入理解Shiro
安全框架Shiro和SpringSecurity的比较
首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。
Java编程指南
2020/05/13
8880
shiro实战之常见问题整理
在调用subject.login时会调用UserRealm的doGetAuthenticationInfo方法。
山行AI
2019/08/06
1.2K0
Shiro简介及SpringBoot集成Shiro(狂神说视频简易版)
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环
刘大猫
2025/06/01
1140
【Spring Boot】014-Shiro登录拦截和用户认证
/* * anon:无需认证就可以访问; * authc:必须认证了才能访问; * user:必须拥有记住我功能才能访问(一般不用); * perms:拥有对某个资源的权限才能访问; * role:拥有某个角色权限才能访问; */
訾博ZiBo
2025/01/06
1260
【Spring Boot】014-Shiro登录拦截和用户认证
Shiro高级及与项目的认证授权(二)
Realm域:Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源
用户1289394
2023/09/25
2700
Shiro高级及与项目的认证授权(二)
【Spring Boot】017-Shiro整合Thymeleaf
链接:https://pan.baidu.com/s/1UcX7tWIBZxJtt4ViGYC2mg 提取码:zibo 复制这段内容后打开百度网盘手机App,操作更方便哦
訾博ZiBo
2025/01/06
1110
【Spring Boot】017-Shiro整合Thymeleaf
SpringBoot整合jsp,Druid数据监控,与Shiro,快速为实体类添加相应方法
一.在SpringBoot项目中, 如何能够使用并运行Jsp页面? 1.添加相应jar包坐标 <dependency> <groupId>javax.servletgroupId> <
时间静止不是简史
2021/03/04
8000
SpringBoot整合jsp,Druid数据监控,与Shiro,快速为实体类添加相应方法
(八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)
姗姗来迟的第八篇,这一篇姑且认为 Springboot 的基础整合部分已经算结束了,或许还会写一些相关的,还有MySQL没有重新整理的,Linux相关的,以及我以前记录下来的一些坑,和常见错误,都会整理出来,因为太忙,更新会慢一些,感谢大家支持!
BWH_Steven
2020/07/15
1.1K0
(八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)
Springboot整合shiro框架
4. 编写前端页面 在templates目录下编写 login.html,add.html,delete.html,index.html 导入thymeleaf的dtd
JokerDJ
2023/11/27
3650
Springboot整合shiro框架
springboot 整合 springSecurity 和shiro
SpringSecurity 安全简介 1、在 Web 开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。因此,从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中。
kirin
2021/04/30
1.2K0
SpringBoot 整合 Shiro 实现登录拦截
上面设置user 目录下所有资源的访问均需认证后才可访问,未认证访问时,会自动跳转到登录页面,即表示登录拦截成功。
FHAdmin
2021/09/13
8810
开发|ShiroConfig实现基础拦截
Subjrct:用户主体(登录,注销,判断授权等等一些的方法)(把操作交给SecurityManager)
算法与编程之美
2020/10/26
1.7K0
shiro安全框架从入门到精通实战!!!!
2、abstaract的mehtod能不能是static,同时是native, 同步的?
张哥编程
2024/12/13
1430
安全框架shiro和springSecurity的比较
首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。
软件小生活
2022/03/29
8510
安全框架shiro和springSecurity的比较
使用Shiro实现认证和授权(基于SpringBoot)
Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案。下面是在SpringBoot中使用Shiro进行认证和授权的例子,代码如下:
布禾
2020/10/29
8520
Spring Boot 整合Shiro
Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 的易于理解的 API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
LCyee
2020/08/05
1K0
Spring Boot 整合Shiro
Spring Boot:整合Shiro权限框架
Shiro是Apache旗下的一个开源项目,它是一个非常易用的安全框架,提供了包括认证、授权、加密、会话管理等功能,与Spring Security一样属基于权限的安全框架,但是与Spring Security 相比,Shiro使用了比较简单易懂易于使用的授权方式。Shiro属于轻量级框架,相对于Spring Security简单很多,并没有security那么复杂。
朝雨忆轻尘
2019/06/21
1.4K0
Spring Boot:整合Shiro权限框架
Shiro安全框架
一个功能强大且易于使用的Java安全框架,它执行身份验证、授权、加密和会话管理。
暴躁的程序猿
2022/03/24
4360
Shiro安全框架
相关推荐
springboot整合shior初体验
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档