来自:https://www.cnblogs.com/zoli/p/11236799.html

两个基本的概念

安全实体:系统需要保护的具体对象数据

权限:系统相关的功能操作,例如基本的CRUD

 Shiro  

首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。

Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。如下是它所具有的特点:

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

Shiro四大核心功能:Authentication,Authorization,Cryptography,Session Management

Shiro架构

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

Subject:主体,可以看到主体可以是任何可以与应用交互的 “用户”;

SecurityManager:相当于 SpringMVC 中的 DispatcherServlet 或者 Struts2 中的 FilterDispatcher;是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理。

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

  1. 两个配置类ShiroConfigUserRealm
  1. 1 package com.example.shirodemo.config;
  2. 2
  3. 3 import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
  4. 4 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
  5. 5 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  6. 6 import org.springframework.beans.factory.annotation.Qualifier;
  7. 7 import org.springframework.context.annotation.Bean;
  8. 8 import org.springframework.context.annotation.Configuration;
  9. 9
  10. 10 import java.util.LinkedHashMap;
  11. 11 import java.util.Map;
  12. 12
  13. 13 /**
  14. 14 * shiro配置类
  15. 15 */
  16. 16 @Configuration
  17. 17 public class ShiroConfig {
  18. 18 /**
  19. 19 * 创建ShiroFilterFactoryBean
  20. 20 */
  21. 21 @Bean
  22. 22 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
  23. 23 ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
  24. 24 //设置安全管理器
  25. 25 shiroFilterFactoryBean.setSecurityManager(securityManager);
  26. 26 //添加Shiro拦截器
  27. 27 /**
  28. 28 * Shiro 内置过滤器,可以实现权限相关的拦截器
  29. 29 * anon:无需认证(登录)可以直接访问
  30. 30 * authc:必须认证才能访问
  31. 31 * user:如果使用rememberMe的功能才可以访问
  32. 32 * perms:该资源得到资源权限才可以访问
  33. 33 * role:该资源必须得到角色权限才可以访问
  34. 34 */
  35. 35 Map<String,String> filterMap=new LinkedHashMap<>();
  36. 36 /* filterMap.put("/add","authc");
  37. 37 filterMap.put("/update","authc");*/
  38. 38 // filterMap.put("/test","anon");
  39. 39 filterMap.put("/login","anon");
  40. 40 //添加Shiro授权拦截器
  41. 41 filterMap.put("/add","perms[添加]");
  42. 42 filterMap.put("/foresee","perms[预言未来]");
  43. 43 filterMap.put("/update","perms[修改]");
  44. 44 filterMap.put("/delete","perms[删除]");
  45. 45 //filterMap.put("/update","perms[]");
  46. 46 //filterMap.put("/delete","perms[]");
  47. 47 //filterMap.put("/getAll","perms[]");
  48. 48 filterMap.put("/*","authc");
  49. 49 //跳转到登陆的页面
  50. 50 shiroFilterFactoryBean.setLoginUrl("/tologin");
  51. 51 //设置未授权的页面
  52. 52 shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");
  53. 53 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
  54. 54
  55. 55 return shiroFilterFactoryBean;
  56. 56 }
  57. 57 /**
  58. 58 * 创建DefaultWebSecurityManager
  59. 59 */
  60. 60 @Bean("securityManager")
  61. 61 public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
  62. 62 DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
  63. 63 //关联Realm
  64. 64 securityManager.setRealm(userRealm);
  65. 65 return securityManager;
  66. 66 }
  67. 67 /**
  68. 68 * 创建Realm
  69. 69 */
  70. 70 @Bean("userRealm")
  71. 71 public UserRealm getRealm(){
  72. 72 UserRealm userRealm=new UserRealm();
  73. 73 return userRealm;
  74. 74 }
  75. 75 /**
  76. 76 * 配置shiroDialect,用于thymeleaf和shiro标签配合使用
  77. 77 */
  78. 78 @Bean
  79. 79 public ShiroDialect getShiroDialect(){
  80. 80 ShiroDialect shiroDialect=new ShiroDialect();
  81. 81 return shiroDialect;
  82. 82 }
  83. 83 }
  1.  
  1. package com.example.shirodemo.config;
  2.  
  3. import com.example.shirodemo.bean.Permission;
  4. import com.example.shirodemo.bean.User;
  5. import com.example.shirodemo.service.IPermissionService;
  6. import com.example.shirodemo.service.IUserService;
  7. import org.apache.shiro.SecurityUtils;
  8. import org.apache.shiro.authc.*;
  9. import org.apache.shiro.authz.AuthorizationInfo;
  10. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  11. import org.apache.shiro.realm.AuthorizingRealm;
  12. import org.apache.shiro.subject.PrincipalCollection;
  13. import org.apache.shiro.subject.Subject;
  14. import org.springframework.security.core.GrantedAuthority;
  15. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  16.  
  17. import javax.annotation.Resource;
  18. import java.util.ArrayList;
  19. import java.util.List;
  20.  
  21. /**
  22. * 自定义Realm
  23. */
  24. public class UserRealm extends AuthorizingRealm {
  25. @Resource
  26. private IUserService userService;
  27. @Resource
  28. private IPermissionService permissionService;
  29. /**
  30. * 执行授权逻辑
  31. * @param principalCollection
  32. * @return
  33. */
  34. @Override
  35. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  36. System.out.println("执行授权逻辑");
  37. /**
  38. * 给资源授权
  39. */
  40. SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
  41. //添加授权字符串
  42. //simpleAuthorizationInfo.addStringPermission("user:add");
  43.  
  44. //--------------------认证账号
  45. Subject subject= SecurityUtils.getSubject();
  46. User user=(User)subject.getPrincipal();
  47. User user1=userService.findById(user.getId());
  48. if(user1==null){
  49. //用户名不存在
  50. return null;
  51. }
  52. //-------------------开始授权
  53. List<Permission> permissions =permissionService.getPermissionByUserId(user1.getId());
  54. for (Permission per : permissions) {
  55. simpleAuthorizationInfo.addStringPermission(per.getName());
  56. System.out.println("拥有权限:"+per.getName());
  57. }
  58. return simpleAuthorizationInfo;
  59. }
  60.  
  61. /**
  62. * 执行认证逻辑
  63. * @param authenticationToken
  64. * @return
  65. * @throws AuthenticationException
  66. */
  67. @Override
  68. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
  69. System.out.println("执行认证逻辑");
  70. /**
  71. * 判断ShiroRealm逻辑UsernamePasswordToken是否正确
  72. */
  73. //1判断用户名
  74. UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)authenticationToken;
  75. User user=userService.findByname(usernamePasswordToken.getUsername());
  76. if(user==null){
  77. //用户名不存在
  78. return null;
  79. }
  80. //判断密码是否正确
  81. return new SimpleAuthenticationInfo(user,user.getPassword(),"");
  82. }
  83. }

认证过程

  1. 1 /**
  2. 2 * 登录逻辑处理
  3. 3 */
  4. 4 @RequestMapping("/login")
  5. 5 public String login(User user, Model model) {
  6. 6 /**
  7. 7 *使用shiro编写认证操作
  8. 8 */
  9. 9 //1:获取subject
  10. 10 Subject subject = SecurityUtils.getSubject();
  11. 11 //2:封装用户账号和密码
  12. 12 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
  13. 13 //3:执行登录方法
  14. 14 try {
  15. 15 subject.login(usernamePasswordToken);
  16. 16 model.addAttribute(user);
  17. 17 //登录成功
  18. 18 //成功后跳转到
  19. 19 //return "redirect:/test";
  20. 20 return "/test";
  21. 21 } catch (UnknownAccountException e) {
  22. 22 //e.printStackTrace();
  23. 23 //登录失败用户名不存在
  24. 24 model.addAttribute("msg","用户名不存在");
  25. 25 return "login";
  26. 26 }catch (IncorrectCredentialsException e){
  27. 27 //登录失败密码错误
  28. 28 model.addAttribute("msg","密码错误");
  29. 29 return "login";
  30. 30 }
  31. 31 }
  32. 32 }
  1.  

Subject拿到用户数据后走UserRealm 类里面的认证逻辑,授权过程比较简单可以看你上面的代码,

     Shiro配置拦截器

 //添加Shiro拦截器
27         /**
28          * Shiro 内置过滤器,可以实现权限相关的拦截器
29          *     anon:无需认证(登录)可以直接访问
30          *     authc:必须认证才能访问
31          *     user:如果使用rememberMe的功能才可以访问
32          *     perms:该资源得到资源权限才可以访问
33          *     role:该资源必须得到角色权限才可以访问
34          */

   Spring Security

除了不能脱离Spring,shiro的功能它都有。而且Spring Security对Oauth、OpenID也有支持,Shiro则需要自己手动实现。Spring Security的权限细粒度更高,毕竟Spring Security是Spring家族的。

 Spring Security一般流程为:

①当用户登录时,前端将用户输入的用户名、密码信息传输到后台,后台用一个类对象将其封装起来,通常使用的是UsernamePasswordAuthenticationToken这个类。

②程序负责验证这个类对象。验证方法是调用Service根据username从数据库中取用户信息到实体类的实例中,比较两者的密码,如果密码正确就成功登陆,同时把包含着用户的用户名、密码、所具有的权限等信息的类对象放到SecurityContextHolder(安全上下文容器,类似Session)中去。

③用户访问一个资源的时候,首先判断是否是受限资源。如果是的话还要判断当前是否未登录,没有的话就跳到登录页面。

④如果用户已经登录,访问一个受限资源的时候,程序要根据url去数据库中取出该资源所对应的所有可以访问的角色,然后拿着当前用户的所有角色一一对比,判断用户是否可以访问。

注:

OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。

OpenID 系统的第一部分是身份验证,即如何通过 URI 来认证用户身份。目前的网站都是依靠用户名和密码来登录认证,这就意味着大家在每个网站都需要注册用户名和密码,即便你使用的是同样的密码。如果使用 OpenID ,你的网站地址(URI)就是你的用户名,而你的密码安全的存储在一个 OpenID 服务网站上(你可以自己建立一个 OpenID 服务网站,也可以选择一个可信任的 OpenID 服务网站来完成注册)。

与OpenID同属性的身份识别服务商还有ⅥeID,ClaimID,CardSpace,Rapleaf,Trufina ID Card等,其中ⅥeID通用账户的应用最为广泛。

Spring Security和Shiro

相同点:

    1:认证功能

    2:授权功能

    3:加密功能

    4:会话管理

    5:缓存支持

    6:rememberMe功能.......

不同点:

     优点:

     1:Spring Security基于Spring开发,项目中如果使用Spring作为基础,配合Spring Security做权限更加方便,而Shiro需要和Spring进行整合开发

     2:Spring Security功能比Shiro更加丰富些,例如安全防护

     3:Spring Security社区资源比Shiro丰富

     缺点:

      1:Shiro的配置和使用比较简单,Spring Security上手复杂

      2:Shiro依赖性低,不需要任何框架和容器,可以独立运行,而Spring Security依赖于Spring容器 

安全框架Shiro和SpringSecurity的比较的更多相关文章

  1. 安全框架Shiro

    原文地址:https://www.cnblogs.com/learnhow/p/5694876.html 一.架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精 ...

  2. Java安全(权限)框架 - Shiro 功能讲解 架构分析

    Java安全(权限)框架 - Shiro 功能讲解 架构分析 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 简述Shiro Shiro出自公司Apache(阿帕奇),是java的一 ...

  3. Java 权限框架 Shiro 实战二:与spring集成、filter机制

    转自:https://www.cnblogs.com/digdeep/archive/2015/07/04/4620471.html Shiro和Spring的集成,涉及到很多相关的配置,涉及到shi ...

  4. 安全框架--shiro

    安全框架--shiro 0.2 名词及含义 SecurityManager:安全管理器,由框架提供的,整个shiro框架最核心的组件. Realm:安全数据桥,类似于项目中的DAO,访问安全数据的,框 ...

  5. 安全框架 - Shiro与springMVC整合的注解以及JSP标签

    Shiro想必大家都知道了,之前的文章我也有提过,是目前使用率要比spring security都要多的一个权限框架,本身spring自己都在用shiro,之前的文章有兴趣可以去扒一下 最近正好用到s ...

  6. 权限控制框架Shiro简单介绍及配置实例

    Shiro是什么 http://shiro.apache.org/ Apache Shiro是一个非常易用的Java安全框架,它能提供验证.授权.加密和Session控制.Shiro非常轻量级,而且A ...

  7. 安全框架Shiro和Spring Security比较

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势. Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证. ...

  8. 用户登录安全框架shiro—用户的认证和授权(一)

     ssm整合shiro框架,对用户的登录操作进行认证和授权,目的很纯粹就是为了增加系统的安全线,至少不要输在门槛上嘛. 这几天在公司独立开发一个供公司内部人员使用的小管理系统,客户不多但是登录一直都是 ...

  9. 安全框架Shiro入门

    Shiro简介 Apache Shiro是Java的一个安全框架,官网为shiro.apache.org,主要场景为控制登陆,判断用户是否有访问某个功能的权限等等. Shiro的核心功能(入门知识,只 ...

随机推荐

  1. JS-T

    取整函数ceil:向上取整floor:向下取整round:四舍五入 js获取当前页面信息this.location.href JS打印对象 var data = JSON.stringify(res. ...

  2. NIO入门

    NIO:Non-blocking IO,即非阻塞式IO. 标准的IO基于字节流和字符流进行操作. 而NIO基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从Channel读取到Bu ...

  3. IIS7多站点ssl配置及http自动跳转到https

    SSL证书配置参考如下: http转https实战教程iis7.5 window08 IIS7安装多域名SSL证书绑定443端口 关键是修改C:\Windows\System32\inetsrv\co ...

  4. Java基础(六)

    面向对象 概述 生活举例 代码体验 类与对象的关系 类的定义 根据类创建对象 对象的基本使用 练习:手机类与对象 内存图:一个对象 内存图:两个对象 内存图:同一个对象 局部变量与成员变量的区别 pr ...

  5. python多线程学习(一)

    python多线程.多进程 初探 原先刚学Java的时候,多线程也学了几天,后来一直没用到.然后接触python的多线程的时候,貌似看到一句"python多线程很鸡肋",于是乎直接 ...

  6. F. Greedy Sequence(主席树区间k的后继)(The Preliminary Contest for ICPC Asia Nanjing 2019)

    题意: 查找区间k的后继. 思路: 直接主席树. #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #include <cstdio&g ...

  7. 虚拟机无法启动,提示:无法打开内核功能扩展“com.vmware.kext.vmci”: 无此文件或目录

    打开 系统偏好设置->安全性与隐私->允许打开 即可

  8. markdown图片转换demo

    markdown图片转换demo 一直以来都是用Markdown来写博客的,但是它的图片嵌入实在是太让人头秃,逼得我能找网上的图片就不用自己的,实在是麻烦.所以我在发现了一个可以生成markdown样 ...

  9. Hadoop大数据平台入门——HDFS和MapReduce

    随着硬件水平的不断提高,需要处理数据的大小也越来越大.大家都知道,现在大数据有多火爆,都认为21世纪是大数据的世纪.当然我也想打上时代的便车.所以今天来学习一下大数据存储和处理. 随着数据的不断变大, ...

  10. Linu目录结构和创建用户

    具体目标结构 ./bin [重点] (/usr/bin./usr/local/bin) ●是Binary的速写,这个目录存放着最经常使用的命令. ./sbin (/usr/sbin./usr/loca ...