SpringBoot与Shiro整合
SpringBoot与Shiro整合
Shiro基本概念
- 先从官网盗一点概念下来:
- Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
- Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
Apache Shiro 体系结构
Apache Shiro 体系结构
- 1、Authentication 认证 —- 用户登录
- 2、Authorization 授权 — 用户具有哪些权限
- 3、Cryptography 安全数据加密
- 4、Session Management 会话管理
- 5、Web Integration web系统集成
- 6、Interations 集成其它应用,spring、缓存框架
关于Shiro的Quickstart
官方Quickstart:
http://shiro.apache.org/10-minute-tutorial.html
Springboot 整合Shiro
- 本次实验基于Springboot的一个基本登录案例来测试Shiro的安全认证、授权功能
- 要使用Shiro我们需要ShiroFilterFactoryBean
- 而ShiroFilterFactoryBean需要设置DefaultWebSecurityManager管理器
- 而DefaultWebSecurityManager需要设置UserRealm
- 于是整个shiro的配置就变成这样:
package zstu.edu.springboot.shiro; 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 java.util.LinkedHashMap; import java.util.Map; /** * shiro的配置类 * Created by CHEN on 2019/7/20. */ @Configuration public class ShiroConfig { /** * 创建ShiroFilterFactoryBean * * @return */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //添加shiro的内置过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截器 * 常用过滤器: * anon:无需认证(登录)可以访问 * authc:必须认证才可以访问 * user:如果使用rememberMe的功能可以直接访问 * perms:该资源必须得到资源权限才可以访问 * role:该资源必须得到角色权限才可以访问 */ Map<String,String> filterMap = new LinkedHashMap<>(); // filterMap.put("/add","authc"); // filterMap.put("/update","authc"); //可以这么写 //这里应当注意顺序,上下换一下就算设置了anon还是会被拦截, //而且目前的顺序会先调用/testThymeleaf,然后再调用login,login还是调用了,只是因为权限是anon所以才没有彖传 //testThymeleaf.......... //login................ filterMap.put("/testThymeleaf","anon"); filterMap.put("/login","anon"); //授权过滤器 //当前授权拦截后shiro会自动跳转到未授权页面 filterMap.put("/add","perms[user:add]"); filterMap.put("/*","authc"); //修改默认登陆界面 shiroFilterFactoryBean.setLoginUrl("/tologin"); //设置未授权提示页面 shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /** * @Qualifier拿到容器中的UserRealm对象 * 创建DefaultWebSecurityManager */ @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联一个Realm securityManager.setRealm(userRealm); return securityManager; } /** * 创建Realm * * @return */ @Bean(name = "userRealm") public UserRealm getRealm() { return new UserRealm(); } }
- 这里需要注意的是我们需要把定义的组件加到容器中,这样我们才能找到这些组件,@Bean中的name属性也可以不用设置,直接用他的默认名即可
- 而UserRealm也是一个自定义类,他需要继承AuthorizingRealm类
package zstu.edu.springboot.shiro; 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; /** * 自定义Realm * Created by CHEN on 2019/7/20. */ public class UserRealm extends AuthorizingRealm { /** * 执行授权逻辑 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //应当对接数据库,这里为了方便,直接写死 info.addStringPermission("user:add"); return info; } /** * 执行认证的逻辑 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行认证逻辑"); //后续应当从数据库中获得,先写死 String name = "123"; String password = "123"; //判断用户名 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; if (!token.getUsername().equals(name)){ //用户名不存在 return null; //shiro底层会抛出UnKnownAccountException } return new SimpleAuthenticationInfo("",password,""); } }
分析
- 首先,是认证Authentication,认证发生在用户登录,我们需要在controller中写出他的逻辑:
- 步骤如下:
- 1.获取Subject Subject subject = SecurityUtils.getSubject();
- 2.封装用户数据 UsernamePasswordToken
- 3.执行登录方法 subject.login(token);
@RequestMapping("/login") public String login(String name ,String password,Model model) { System.out.println("name="+name); /** * 使用Shiro编写认证操作 */ //1.获取Subject Subject subject = SecurityUtils.getSubject(); //封装用户数据 UsernamePasswordToken token = new UsernamePasswordToken(name,password); //执行登录方法 try { subject.login(token); //登录成功 //跳转到test.html return "redirect:/testThymeleaf"; }catch (UnknownAccountException e ){ model.addAttribute("msg","用户名不存在"); System.out.println("UnknownAccountException...................."); return "login"; }catch (IncorrectCredentialsException e ){ model.addAttribute("msg","密码错误"); System.out.println("IncorrectCredentialsException......................."); return "login"; } }
认证流程:
认证流程
授权流程:
授权流程
最后写一点认证拦截
//这里应当注意顺序,上下换一下就算设置了anon还是会被拦截, //而且目前的顺序会先调用/testThymeleaf,然后再调用login,login还是调用了,只是因为权限是anon所以才没有彖传 //testThymeleaf.......... //login................ filterMap.put("/testThymeleaf","anon"); filterMap.put("/login","anon"); filterMap.put("/*","authc"); //所以个人认为避免全拦截的好,拦截的方统一目录下,在认证拦截的时候只需要拦截这个文件下所有文件的请求
原文地址:https://www.jianshu.com/p/86a60e475379
相关推荐
-
长连接的心跳及重连设计 Java框架
2019-4-5
-
Spring源码-AOP(七)-整合AspectJ Java框架
2020-6-8
-
Netty 编解码技术 数据通信和心跳监控案例 Java框架
2019-5-10
-
SpringMvc接口中转设计(策略+模板方法) Java框架
2019-5-13
-
spring boot 1.5.2部署到JBoss 8.1出错解决办法 Java框架
2020-6-8
-
使用Spring Boot和Kotlin创建RESTfull API Java框架
2020-7-4
-
eclipse开发springboot配置文件没有语法提示了 Java框架
2020-7-4
-
Spring Boot 2 实战:mock测试你的web应用 Java框架
2019-10-14
-
Spring如何实现AOP,请不要再说cglib了! Java框架
2020-6-1
-
Spring Cloud构建微服务架构(一)服务注册与发现 Java框架
2019-3-27