jwt、shiro、spring-security的区别

session 原理
客户端(浏览器)第一次访问服务器的时候(一般为访问 servlet 或者 jsp,html 不会产生session),请求中不携带任何标识给服务器,服务器无法找到与之对应的 session,所以会新建 session 对象,并将 session 标识放到响应头的 Set-Cookie中,以 key-value 形式返回给客户端,例:JSESSIONID=7F149950097E7B5B41B390436497CD21; JSESSIONID 是固定的key,value 值是给该客户端新创建的 session 的 ID,之后的请求客户端会将此 key-value 放到 cookie 中一并请求服务器,服务器根据此 ID 寻找对应的 session 对象了;

注意:当浏览器关闭后,会话结束,由于 cookie 消失所以对应的 session 对象标识消失,而对应的服务器上的 session 依然存在,但已经成为报废数据等待 GC 回收了。
对应 session 的 ID 可以利用此方法得到:session.getId();

HttpSession(接口)
HttpSession 是 Java 平台对 session 机制的实现规范,仅仅是个接口,具体到每个 web 应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。

HttpSession 生命周期
若 Servlet 是客户端访问的第一个WEB应用的资源,则只有调用了 request.getSession() 或request.getSession(true) 才会创建 HttpSession 对象。

如何获取
request.getSession(boolean create)

create 为 false,若没有和当前JSP页面关联的 HttpSession 对象,则返回 null;若有返回
create 为 true,若没有 HttpSession 对象,服务器创建一个新的 HttpSession 返回,若有就返回关联的

request.getSession() 等同于request.getSession(true)

什么时候销毁
直接调用HttpSession的invalidate()方法:使HttpSession失效
服务器卸载了当前 Web 应用。
超出 HttpSession 的过期时间。

JWT的Token认证机制实现
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

概括: 简言之 JWT 的 Token 就是服务端签发的字符串是由 base64 后的 header(第一部分) + base64 后的 payload(第二部分) + 对前两者拼接后的字符进行加盐 secret 组合加密的(第三部分) 三部分用.间隔,这个字符串一般每次请求都放在请求头里如 Authorization:Bearer +上面token字符串,服务端每次先取出这个字符串校验,无状态(也称:服务端可扩展行):Token机制在服务端不需要存储 session 信息,因为 Token 自身包含了所有登录用户的信息,只需要在客户端的 cookie 或本地介质存储状态信息

1 什么是JWT
​ JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

2 JWT 组成
一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
1
头部(Header)
头部用于描述关于该 JWT 的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个 JSON 对象。
在头部指明了签名算法是 HS256 算法。 我们进行 BASE64 编码 http://base64.xpcha.com/,编码后的字符串
如下: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9,Base64是一种基于64个可打印字符来表示二进制数据的表示方法

载荷(playload)
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,
这些有效信息包含三个部分{“typ”:“JWT”,“alg”:“HS256”}
(1)标准中注册的声明(建议但不强制使用)
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

(2)公共的声明
	公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
(3)私有的声明
	私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
	这个指的就是自定义的claim。比如前面那个结构举例中的admin和name都属于自定的claim。这些claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在
	拿到JWT之后,都知道怎么对这些标准的claim进行验证(还不知道是否能够验证);而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。
定义一个payload:
	{"sub":"1234567890","name":"John Doe","admin":true}
	然后将其进行base64编码,得到Jwt的第二部分: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

签证(signature)
jwt 的第三部分是一个签证信息,这个签证信息由三部分组成:
header (base64后的)
payload (base64后的)
secret

这个部分需要 base64 加密后的 header 和 base64 加密后的payload使用.连接组成的字符串,然后通过header 中声明的加密方式进行加盐secret组合加密,
然后就构成了jwt的第三部分: TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
将这三部分用.连接成一个完整的字符串,构成了最终的jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret 是保存在服务器端的,jwt 的签发生成也是在服务器端的,secret 就是用来进行 jwt 的签发和 jwt 的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发 jwt 了。

优缺点
优点
1.更适用于移动应用: Cookie 不支持手机端访问的
2.无状态

缺点
1.注销登录等场景下 token 还有效

退出登录;
修改密码;
服务端修改了某个用户具有的权限或者角色;
用户的帐户被删除/暂停。
用户由管理员注销; 都有这些问题

解决方案

将 token 存入内存数据库如 redis。如果需要让某个 token 失效就直接从 redis 中删除这个 token。但这样需每次使用 token 发送请求都要先从 DB 中查询 token 是否存在的步骤,且违背 JWT 无状态原则。
1
2.token 的续签问题
颁发时有效期设置多久合适?都不合适
折中解决方案:每次请求时校验还有多久过期,快过期重新颁发,这也牺牲了性能

Shiro 和 spring-security
Apache Shiro 是一个强大且易用的Java安全框架,【身份验证、授权、密码加密和会话管理】

shiro的主要功能、核心组件
主要功能

Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
核心组件

Subject:subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
SecuritryManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
可以将Realm类比为SpringMVC中的Dao层(比他更加安全)。
认证和授权

Realm 是真正负责处理认证和授权的组件。
SecurityManager 要完成认证,要 Realm 返回一个 AuthenticationInfo 携带存储库中用户认证信息,用来与提交的信息进行比对,如不匹配,会认证失败。
SecurityManager 要完成授权,需要 Realm 返回一个 AuthorizationInfo

认证依赖于方法 doGetAuthenticationInfo
授权依赖于方法 doGetAuthorizationInfo
supports(AuthenticationToken token) 方法可以处理非 UsernamePasswordToken 的情况。

public class MyRealm extends AuthorizingRealm {
// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Object principal = principals.getPrimaryPrincipal();
System.out.println(“RealmForDouble授权中---->用户:”+principal);
SimpleAuthorizationInfo info = null;
Set roles = new HashSet<>();
if (“admin”.equals(principal)){
roles.add(“admin”);
}
if (“guest”.equals(principal)){
roles.add(“guest”);
}
info = new SimpleAuthorizationInfo(roles);
return info;
}
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println(“RealmForDouble认证中---->用户:”+token.getPrincipal());
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String password=“123456”;// 假设这是从数据库中查询到的用户密码
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(upToken.getUsername(),password,this.getName());
return info;
}
}

shiro+redis 实现 session 共享
实现逻辑就是 shiro 的拦截器会首先去 redis 里面获取 session ,作为当本次请求的 session

优缺点对比

shiro的优点

shiro的代码更易于阅读,且使用更加简单;
shiro可以用于非web环境,不跟任何框架或容器绑定,独立运行;

shiro 通过 filter 过滤器拦截请求判断是否需要登录,校验 session 是否合法(是否登录了)
shiro 可以做登录和授权,我们只用了登录功能,是否有权限访业务功能是通过人员、角色、权限表来控制的

shiro 的缺点

授权第三方登录需要手动实现;
spring-security 的优点

spring-security对spring结合较好,项目是spring-boot等搭建的,使用起来更加方便;
有更好的spring社区进行支持;
支持oauth授权,官方网站:spring-security-oauth

spring-security的缺点

相比shiro,spring-security比较复杂,没有shiro清晰易懂;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Security是Spring家族的一个安全管理框架,相比于另一个安全框架Shiro,它具有更丰富的功能。一般中大型项目都是使用Spring Security做安全框架,而Shiro上手比较简单。\[2\] JWT是一种用于身份验证和授权的开放标准,它定义了一种紧凑且自包含的方式来传输信息。JWT由三部分组成:头部、载荷和签名。头部包含了加密算法和类型信息,载荷包含了要传输的数据,签名用于验证数据的完整性和真实性。\[3\] 在Spring Security中集成JWT可以通过以下步骤实现: 1. 认证配置:配置Spring Security的认证流程,包括用户认证和生成JWT的逻辑。 2. 权限配置:配置Spring Security的权限控制,包括对不同角色和资源的访问控制。 通过以上配置,Spring Security可以使用JWT进行身份验证和授权,保护应用程序的安全性。 #### 引用[.reference_title] - *1* *2* [Spring Security+JWT简述](https://blog.csdn.net/jiangnb520/article/details/124921240)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring Security 之 JWT介绍](https://blog.csdn.net/weixin_40972073/article/details/126844751)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值