Spring Boot整合Shiro实现认证与授权 您所在的位置:网站首页 教室拍照文案怎么写 Spring Boot整合Shiro实现认证与授权

Spring Boot整合Shiro实现认证与授权

#Spring Boot整合Shiro实现认证与授权| 来源: 网络整理| 查看: 265

SpringBoot整合Shiro实现认证与授权 简介 什么是shiro?

Shiro是一个强大的简单易用的Java安全框架,主要用来更便捷的认证,授权,加密,会话管理。Shiro首要的和最重要的目标就是容易使用并且容易理解。

首先明白几个概念:shiro三个核心组件 Subject : 用户主体,即当前操作用户(它把操作交给SecurityManager)。 所有Subject都需要SecurityManager,当你与Subject进行交互,这些交互行为实际上被转换为与SecurityManager的交互。SecurityManager : 安全管理器或安全管理员(它关联 Realm)。 Shiro架构的核心,它就像Shiro内部所有原件的保护伞。然而一旦配置了SecurityManager,SecurityManager就用到的比较少,开发者大部分时间都是和Subject打交道。Realm : 是Shiro连接数据的桥梁。 充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行==认证 (登录) ==和 ==授权(访问控制)==验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。 shiro能做什么?

在这里插入图片描述

shiro认证工作流程:

在这里插入图片描述 认证流程: 在这里插入图片描述 授权流程: 在这里插入图片描述 Shiro相关类介绍: (1)Authentication :认证 ---- 用户登录 (2)Authorization :授权 — 用户具有哪些权限 (3)Cryptography :安全数据加密 (4)Session Management :会话管理 (5)Web Integration :web系统集成 (6)Interations: 集成其它应用,spring、缓存框架

Shiro 特点: (1)易于理解的 Java Security API; (2)简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等); (3)对角色的简单的签权(访问控制),支持细粒度的签权; (4)支持一级缓存,以提升应用程序的性能; (5)内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境; (6)异构客户端会话访问; (7)非常简单的加密 API; (8)不跟任何的框架或者容器捆绑,可以独立运行

SpringBoot整合Shiro实现认证与授权验证 第一步:pom文件导入相关依赖 org.apache.shiro shiro-spring 1.4.0 mysql mysql-connector-java runtime org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.2 com.alibaba druid 1.1.9 org.springframework.boot spring-boot-starter-thymeleaf 第二步,编写一个shiro配置类

因为shiro有三个核心的组件,并且shiro主要通过过滤器进行拦截请求来实现安全控制。因此,编写一个配置类依次创建对应的bean对象,放入spring容器。

/** * shiro的配置类 */ @Configuration public class ShiroConfig { /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器(关联SecurityManager) shiroFilterFactoryBean.setSecurityManager(securityManager); //============== 开始配置拦截:================== //1.添加Shiro内置过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截器。用于拦截需要权限才能访问资源的请求。 * 常用的过滤器: * anon: 无需认证(登录)就可以访问。允许匿名身份访问 * authc: 必须认证才可以访问 * user: 如果使用rememberMe的功能可以直接访问 * perms: 该资源必须得到资源权限才可以访问 * role: 该资源必须得到角色权限才可以访问 */ Map filterMap = new LinkedHashMap(); //添加认证过滤器 //filterMap.put("/api/add","authc"); //filterMap.put("/api/update","authc"); filterMap.put("/api/testThymeleaf","anon"); // 放行该请求。 filterMap.put("/api/login","anon"); // 放行该请求。 //添加授权过滤器 filterMap.put("/api/add","perms[user:add]");// 需要权限才能访问。并且要放在拦截所有的上面才有效。 filterMap.put("/api/update","perms[user:update]"); filterMap.put("/api/*","authc"); // 拦截/api/所有请求 //authc模式拦截后默认跳转到login.jsp页面,无论有没有该页面。 // 修改调整的登陆页面 shiroFilterFactoryBean.setLoginUrl("/api/toLogin"); //设置未授权提示页面 shiroFilterFactoryBean.setUnauthorizedUrl("/api/unAuthorized"); 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 * 我们可以先自定义一个Realm类 */ @Bean(name = "userRealm") public UserRealm getRealm(){ return new UserRealm(); } } 第三步,自定义Realm类:一定要继承AuthorizingRealm类,并重写两个方法 public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; /** * 执行授权逻辑 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); //给资源进行授权 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //从数据库中获取授权字符串 Subject subject = SecurityUtils.getSubject(); //subject.getPrincipal()获取的实际上是认证逻辑中return new SimpleAuthenticationInfo(user,user.getPassword(),"")第一个参数 User user = (User) subject.getPrincipal(); User dbUser = userService.findByName(user.getName()); //添加资源的授权字符串 info.addStringPermission(dbUser.getPerm()); return info; } /** * 执行认证逻辑 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行认证逻辑"); //编写shiro判断逻辑,判断用户名和密码 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //数据库中的username:admin和 password:123456 User user = userService.findByName(token.getUsername()); //1.判断用户名 if (user==null){ //用户名不存在 return null; // shiro底层会抛出UnknowAccountException异常; } //2.判断密码。我们只需要返回AuthenticationInfo的一个子类SimpleAuthenticationInfo //第一个参数:返回登录逻辑中login方法结果的数据;第二个参数:数据库密码;第三个参数:shiro的名字 //return new SimpleAuthenticationInfo("",user.getPassword(),""); return new SimpleAuthenticationInfo(user,user.getPassword(),""); } } Controller代码: @Controller @RequestMapping("/api") public class HelloController { //测试主页 @RequestMapping("/testThymeleaf") public String testThymeleaf(Model model){ model.addAttribute("name","SpringBooot整合Shiro"); return "test"; } @RequestMapping("/add") public String add(){ return "/user/add"; } @RequestMapping("/update") public String update(){ return "/user/update"; } //负责跳转到登陆页面 @RequestMapping("/toLogin") public String toLogin(){ return "login"; } //负责跳转到未授权页面 @RequestMapping("/unAuthorized") public String unAuthorized(){ return "/user/unAuthorized"; } //登录处理逻辑 @RequestMapping("/login") public String login(String name,String password,Model model){ System.out.println("name:"+name+" password: "+password); /** * 使用Shiro编写认证(登录)操作 */ //1,获取Subject Subject subject = SecurityUtils.getSubject(); //2,封装用户数据,生成一个令牌 UsernamePasswordToken token = new UsernamePasswordToken(name,password); //3.执行登录方法 try { /*执行该方法时,会自动执行我们定义的UserRealm里doGetAuthenticationInfo方法认证逻辑代码! 为什么?通过查看源码 它底层最终会调用到DefaultWebSecurityManager的login()方法, 而DefaultWebSecurityManager关联了Realm且该方法内使用了AuthenticationInfo对象 故会执行Realm里的认证逻辑。我们自定义了一个Realm类(UserRealm),重写了认证逻辑和授权逻辑方法。 */ subject.login(token); //登录成功 return "redirect:/api/testThymeleaf"; } catch (UnknownAccountException e) { //e.printStackTrace(); //登录失败 model.addAttribute("msg","用户名不存在"); return "login"; //跳回login.html页面。 } catch (IncorrectCredentialsException e){ model.addAttribute("msg","密码错误"); return "login"; //跳回login.html页面。 } } }

application.properties:

#数据库配置 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_shiro?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #下面两个配置可有可无 #配置别名允许实体类使用别名即不区分大小写 mybatis.type-aliases-package=com.itnet.myspringboot.domain # mybatis xml文件的加载地址 mybatis.mapper-locations=classpath:com/itnet/myspringboot/mapper/*Mapper.xml

mapper接口文件:

@Mapper @Repository public interface UserMapper { public User findByName(String name); }

mapper文件:

select * from user where name = #{name}

Service实现类:

@Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public User findByName(String name) { return userMapper.findByName(name); } }

目录结构: 在这里插入图片描述

测试:

在这里插入图片描述 在这里插入图片描述

点击“添加页面”,跳转到登录页面,我输入admin 123456进行登录 在这里插入图片描述 在这里插入图片描述在这里插入图片描述 在这里插入图片描述 数据库里: admin只拥有user:add权限。Jason只拥有user:update权限。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

thymeleaf整合shiro权限标签 org.springframework.boot spring-boot-starter-thymeleaf com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0

只需在shiro配置类中加上

/** * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用 */ @Bean public ShiroDialect getShiroDialecct(){ return new ShiroDialect(); }

在前端页面就可以使用shiro标签了

testThymeleaf 添加页面 更新页面

在这里插入图片描述

拓展:

常见权限框架 Shiro

Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了。对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了。

Spring Security

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。它是一个轻量级的安全框架,它确保基于Spring的应用程序提供身份验证和授权支持。它与Spring MVC有很好地集成,并配备了流行的安全算法实现捆绑在一起。安全主要包括两个操作“认证”与“验证”(有时候也会叫做权限控制)。“认证”是为用户建立一个其声明的角色的过程,这个角色可以一个用户、一个设备或者一个系统。“验证”指的是一个用户在你的应用中能够执行某个操作。在到达授权判断之前,角色已经在身份认证过程中建立了。

Shiro和Spring Security比较

(1)Shiro比Spring更容易使用,实现和最重要的理解 (2)Spring Security更加知名的唯一原因是因为品牌名称 (3)“Spring”以简单而闻名,但讽刺的是很多人发现安装Spring Security很难 (4)Spring Security却有更好的社区支持 (5)Apache Shiro在Spring Security处理密码学方面有一个额外的模块 (6)Spring-security 对spring 结合较好,如果项目用的springmvc ,使用起来很方便。但是如果项目中没有用到spring,那就不要考虑它了。 (7)Shiro 功能强大、且 简单、灵活。是Apache 下的项目比较可靠,且不跟任何的框架或者容器绑定,可以独立运行



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有