安全框架Shiro和SpringSecurity的比较
来自:https://www.cnblogs.com/zoli/p/11236799.html
两个基本的概念
安全实体:系统需要保护的具体对象数据
权限:系统相关的功能操作,例如基本的CRUD
Shiro
首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。
Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。如下是它所具有的特点:
- 易于理解的 Java Security API;
- 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
- 对角色的简单的签权(访问控制),支持细粒度的签权;
- 支持一级缓存,以提升应用程序的性能;
- 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;
- 异构客户端会话访问;
- 非常简单的加密 API;
- 不跟任何的框架或者容器捆绑,可以独立运行。
Shiro四大核心功能:Authentication,Authorization,Cryptography,Session Management
Shiro架构
Shiro三个核心组件:Subject, SecurityManager 和 Realms.
Subject:主体,可以看到主体可以是任何可以与应用交互的 “用户”;
Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
两个配置类ShiroConfig和UserRealm
1 package com.example.shirodemo.config;
2
3 import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
4 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
5 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
6 import org.springframework.beans.factory.annotation.Qualifier;
7 import org.springframework.context.annotation.Bean;
8 import org.springframework.context.annotation.Configuration;
9
10 import java.util.LinkedHashMap;
11 import java.util.Map;
12
13 /**
14 * shiro配置类
15 */
16 @Configuration
17 public class ShiroConfig {
18 /**
19 * 创建ShiroFilterFactoryBean
20 */
21 @Bean
22 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
23 ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
24 //设置安全管理器
25 shiroFilterFactoryBean.setSecurityManager(securityManager);
26 //添加Shiro拦截器
27 /**
28 * Shiro 内置过滤器,可以实现权限相关的拦截器
29 * anon:无需认证(登录)可以直接访问
30 * authc:必须认证才能访问
31 * user:如果使用rememberMe的功能才可以访问
32 * perms:该资源得到资源权限才可以访问
33 * role:该资源必须得到角色权限才可以访问
34 */
35 Map<String,String> filterMap=new LinkedHashMap<>();
36 /* filterMap.put("/add","authc");
37 filterMap.put("/update","authc");*/
38 // filterMap.put("/test","anon");
39 filterMap.put("/login","anon");
40 //添加Shiro授权拦截器
41 filterMap.put("/add","perms[添加]");
42 filterMap.put("/foresee","perms[预言未来]");
43 filterMap.put("/update","perms[修改]");
44 filterMap.put("/delete","perms[删除]");
45 //filterMap.put("/update","perms[]");
46 //filterMap.put("/delete","perms[]");
47 //filterMap.put("/getAll","perms[]");
48 filterMap.put("/*","authc");
49 //跳转到登陆的页面
50 shiroFilterFactoryBean.setLoginUrl("/tologin");
51 //设置未授权的页面
52 shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");
53 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
54
55 return shiroFilterFactoryBean;
56 }
57 /**
58 * 创建DefaultWebSecurityManager
59 */
60 @Bean("securityManager")
61 public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
62 DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
63 //关联Realm
64 securityManager.setRealm(userRealm);
65 return securityManager;
66 }
67 /**
68 * 创建Realm
69 */
70 @Bean("userRealm")
71 public UserRealm getRealm(){
72 UserRealm userRealm=new UserRealm();
73 return userRealm;
74 }
75 /**
76 * 配置shiroDialect,用于thymeleaf和shiro标签配合使用
77 */
78 @Bean
79 public ShiroDialect getShiroDialect(){
80 ShiroDialect shiroDialect=new ShiroDialect();
81 return shiroDialect;
82 }
83 }
package com.example.shirodemo.config; import com.example.shirodemo.bean.Permission;
import com.example.shirodemo.bean.User;
import com.example.shirodemo.service.IPermissionService;
import com.example.shirodemo.service.IUserService;
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.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List; /**
* 自定义Realm
*/
public class UserRealm extends AuthorizingRealm {
@Resource
private IUserService userService;
@Resource
private IPermissionService permissionService;
/**
* 执行授权逻辑
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
/**
* 给资源授权
*/
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
//添加授权字符串
//simpleAuthorizationInfo.addStringPermission("user:add"); //--------------------认证账号
Subject subject= SecurityUtils.getSubject();
User user=(User)subject.getPrincipal();
User user1=userService.findById(user.getId());
if(user1==null){
//用户名不存在
return null;
}
//-------------------开始授权
List<Permission> permissions =permissionService.getPermissionByUserId(user1.getId());
for (Permission per : permissions) {
simpleAuthorizationInfo.addStringPermission(per.getName());
System.out.println("拥有权限:"+per.getName());
}
return simpleAuthorizationInfo;
} /**
* 执行认证逻辑
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行认证逻辑");
/**
* 判断ShiroRealm逻辑UsernamePasswordToken是否正确
*/
//1判断用户名
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)authenticationToken;
User user=userService.findByname(usernamePasswordToken.getUsername());
if(user==null){
//用户名不存在
return null;
}
//判断密码是否正确
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
认证过程
1 /**
2 * 登录逻辑处理
3 */
4 @RequestMapping("/login")
5 public String login(User user, Model model) {
6 /**
7 *使用shiro编写认证操作
8 */
9 //1:获取subject
10 Subject subject = SecurityUtils.getSubject();
11 //2:封装用户账号和密码
12 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
13 //3:执行登录方法
14 try {
15 subject.login(usernamePasswordToken);
16 model.addAttribute(user);
17 //登录成功
18 //成功后跳转到
19 //return "redirect:/test";
20 return "/test";
21 } catch (UnknownAccountException e) {
22 //e.printStackTrace();
23 //登录失败用户名不存在
24 model.addAttribute("msg","用户名不存在");
25 return "login";
26 }catch (IncorrectCredentialsException e){
27 //登录失败密码错误
28 model.addAttribute("msg","密码错误");
29 return "login";
30 }
31 }
32 }
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的比较的更多相关文章
- 安全框架Shiro
原文地址:https://www.cnblogs.com/learnhow/p/5694876.html 一.架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精 ...
- Java安全(权限)框架 - Shiro 功能讲解 架构分析
Java安全(权限)框架 - Shiro 功能讲解 架构分析 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 简述Shiro Shiro出自公司Apache(阿帕奇),是java的一 ...
- Java 权限框架 Shiro 实战二:与spring集成、filter机制
转自:https://www.cnblogs.com/digdeep/archive/2015/07/04/4620471.html Shiro和Spring的集成,涉及到很多相关的配置,涉及到shi ...
- 安全框架--shiro
安全框架--shiro 0.2 名词及含义 SecurityManager:安全管理器,由框架提供的,整个shiro框架最核心的组件. Realm:安全数据桥,类似于项目中的DAO,访问安全数据的,框 ...
- 安全框架 - Shiro与springMVC整合的注解以及JSP标签
Shiro想必大家都知道了,之前的文章我也有提过,是目前使用率要比spring security都要多的一个权限框架,本身spring自己都在用shiro,之前的文章有兴趣可以去扒一下 最近正好用到s ...
- 权限控制框架Shiro简单介绍及配置实例
Shiro是什么 http://shiro.apache.org/ Apache Shiro是一个非常易用的Java安全框架,它能提供验证.授权.加密和Session控制.Shiro非常轻量级,而且A ...
- 安全框架Shiro和Spring Security比较
Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势. Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证. ...
- 用户登录安全框架shiro—用户的认证和授权(一)
ssm整合shiro框架,对用户的登录操作进行认证和授权,目的很纯粹就是为了增加系统的安全线,至少不要输在门槛上嘛. 这几天在公司独立开发一个供公司内部人员使用的小管理系统,客户不多但是登录一直都是 ...
- 安全框架Shiro入门
Shiro简介 Apache Shiro是Java的一个安全框架,官网为shiro.apache.org,主要场景为控制登陆,判断用户是否有访问某个功能的权限等等. Shiro的核心功能(入门知识,只 ...
随机推荐
- python基础 --- 难点重点
循环嵌套 # 打印九九乘法表 for row in range(1,10): # 行与列相乘 for col in range(1,row+1): print(col,'*',row,'=',row ...
- 05-前端之jQuery
一. jQuery是什么? <1> jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. <2> jQuery ...
- python中True,False与0,1之间的关系
demo1 >>> print(True == 1) >>> print(True == 2) >>> print(False == 0) > ...
- Java 200道题
1. junit用法,before,beforeClass,after, afterClass的执行顺序 一个测试类单元测试的执行顺序为: @BeforeClass –> @Before –&g ...
- java,mysql触发器,redis生成流水号(yyyyMM000)
最近又遇到需要根据日期生成流水号的业务,然后记录了几种生成方法,一个是通过java代码,一个是数据库的触发器,还有是通过redis.下面是代码: 通过java生成简易流水: /** * 通过日期和生成 ...
- CDH6.2安装之YUM方式
参考: https://www.sysit.cn/blog/post/sysit/CDH6.2.0%E7%B3%BB%E7%BB%9F%E9%83%A8%E7%BD%B2%E6%89%8B%E5%86 ...
- kafka服务器批量copy文件脚本
#!/bin/bashif [[ $# -lt 1 ]] ; then echo no params ; exit ; fiparams=$@for (( i=1 ; i <= 3 ; i = ...
- 【pytorch】学习笔记(三)-激励函数
[pytorch]学习笔记-激励函数 学习自:莫烦python 什么是激励函数 一句话概括 Activation: 就是让神经网络可以描述非线性问题的步骤, 是神经网络变得更强大 1.激活函数是用来加 ...
- requests库爬取豆瓣热门国产电视剧数据并保存到本地
首先要做的就是去豆瓣网找对应的接口,这里就不赘述了,谷歌浏览器抓包即可,然后要做的就是分析返回的json数据的结构: https://movie.douban.com/j/search_subject ...
- Linux服务器Java进程突然消失排查办法
出处:JAVA进程突然消失的原因? 问题描述 在实际生产环境下,如果我们遇见Java进程突然消失,该如何去排查问题? 思路 可能有几种原因: ①.Java应用程序的问题:发生OOM导致进程Crash ...