• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > Spring Boot(四)之使用JWT和Spring Security保护REST API

Spring Boot(四)之使用JWT和Spring Security保护REST API

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了spring security jwt,spring boot jwt,spring jwt,jwt,jwt连接器官网等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

通常情况下,把API直接暴露出去是风险很大的,不说别的,直接被机器攻击就喝一壶的。那么一般来说,对API要划分出一定的权限级别,然后做一个用户的鉴权,依据鉴权结果给予用户开放对应的API。目前,比较主流的方案有几种:

  1. 用户名和密码鉴权,使用Session保存用户鉴权结果。
  2. 使用OAuth进行鉴权(其实OAuth也是一种基于Token的鉴权,只是没有规定Token的生成方式)
  3. 自行采用Token进行鉴权

第一种就不介绍了,由于依赖Session来维护状态,也不太适合移动时代,新的项目就不要采用了。第二种OAuth的方案和JWT都是基于Token的,但OAuth其实对于不做开放平台的公司有些过于复杂。我们主要介绍第三种:JWT。

什么是JWT?

JWT是 Json Web Token 的缩写。它是基于 RFC 7519 标准定义的一种可以安全传输的 小巧 和 自包含 的JSON对象。由于数据是使用数字签名的,所以是可信任的和安全的。JWT可以使用HMAC算法对secret进行加密或者使用RSA的公钥私钥对来进行签名。

JWT的工作流程

下面是一个JWT的工作流程图。模拟一下实际的流程是这样的(假设受保护的API在/protected中)

  1. 用户导航到登录页,输入用户名、密码,进行登录
  2. 服务器验证登录鉴权,如果改用户合法,根据用户的信息和服务器的规则生成JWT Token
  3. 服务器将该token以json形式返回(不一定要json形式,这里说的是一种常见的做法)
  4. 用户得到token,存在localStorage、cookie或其它数据存储形式中。
  5. 以后用户请求/protected中的API时,在请求的header中加入 Authorization: Bearer xxxx(token)。此处注意token之前有一个7字符长度的 Bearer
  6. 服务器端对此token进行检验,如果合法就解析其中内容,根据其拥有的权限和自己的业务逻辑给出对应的响应结果。
  7. 用户取得结果

JWT工作流程图

为了更好的理解这个token是什么,我们先来看一个token生成后的样子,下面那坨乱糟糟的就是了。

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3YW5nIiwiY3JlYXRlZCI6MTQ4OTA3OTk4MTM5MywiZXhwIjoxNDg5Njg0NzgxfQ.RC-BYCe_UZ2URtWddUpWXIp4NMsoeq2O6UF-8tVplqXY1-CI9u1-a-9DAAJGfNWkHE81mpnR3gXzfrBAB3WUAg
但仔细看到的话还是可以看到这个token分成了三部分,每部分用 . 分隔,每段都是用 Base64 编码的。如果我们用一个Base64的解码器的话 ( https://www.base64decode.org/ ),可以看到第一部分 eyJhbGciOiJIUzUxMiJ9 被解析成了:

{
 "alg":"HS512"
}
</div>

这是告诉我们HMAC采用HS512算法对JWT进行的签名。

第二部分 eyJzdWIiOiJ3YW5nIiwiY3JlYXRlZCI6MTQ4OTA3OTk4MTM5MywiZXhwIjoxNDg5Njg0NzgxfQ 被解码之后是

{
 "sub":"wang",
 "created":1489079981393,
 "exp":1489684781
}
</div>

这段告诉我们这个Token中含有的数据声明(Claim),这个例子里面有三个声明:sub, created 和 exp。在我们这个例子中,分别代表着用户名、创建时间和过期时间,当然你可以把任意数据声明在这里。

看到这里,你可能会想这是个什么鬼token,所有信息都透明啊,安全怎么保障?别急,我们看看token的第三段 RC-BYCe_UZ2URtWddUpWXIp4NMsoeq2O6UF-8tVplqXY1-CI9u1-a-9DAAJGfNWkHE81mpnR3gXzfrBAB3WUAg。同样使用Base64解码之后,咦,这是什么东东

D X    DmYTeȧLUZcPZ0$gZAY_7wY@

最后一段其实是签名,这个签名必须知道秘钥才能计算。这个也是JWT的安全保障。这里提一点注意事项,由于数据声明(Claim)是公开的,千万不要把密码等敏感字段放进去,否则就等于是公开给别人了。

也就是说JWT是由三段组成的,按官方的叫法分别是header(头)、payload(负载)和signature(签名):

header.payload.signature

头中的数据通常包含两部分:一个是我们刚刚看到的 alg,这个词是 algorithm 的缩写,就是指明算法。另一个可以添加的字段是token的类型(按RFC 7519实现的token机制不只JWT一种),但如果我们采用的是JWT的话,指定这个就多余了。

{
 "alg": "HS512",
 "typ": "JWT"
}
</div>

payload中可以放置三类数据:系统保留的、公共的和私有的:

  1. 系统保留的声明(Reserved claims):这类声明不是必须的,但是是建议使用的,包括:iss (签发者), exp (过期时间),
  2. sub (主题), aud (目标受众)等。这里我们发现都用的缩写的三个字符,这是由于JWT的目标就是尽可能小巧。
  3. 公共声明:这类声明需要在 IANA JSON Web Token Registry 中定义或者提供一个URI,因为要避免重名等冲突。
  4. 私有声明:这个就是你根据业务需要自己定义的数据了。

签名的过程是这样的:采用header中声明的算法,接受三个参数:base64编码的header、base64编码的payload和秘钥(secret)进行运算。签名这一部分如果你愿意的话,可以采用RSASHA256的方式进行公钥、私钥对的方式进行,如果安全性要求的高的话。

HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)
</div>

JWT的生成和解析

为了简化我们的工作,这里引入一个比较成熟的JWT类库,叫 jjwt ( https://github.com/jwtk/jjwt )。这个类库可以用于Java和Android的JWT token的生成和验证。

JWT的生成可以使用下面这样的代码完成:

String generateToken(Map<String, Object> claims) {
 return Jwts.builder()
 .setClaims(claims)
 .setExpiration(generateExpirationDate())
 .signWith(SignatureAlgorithm.HS512, secret) //采用什么算法是可以自己选择的,不一定非要采用HS512
 .compact();
}
</div>

数据声明(Claim)其实就是一个Map,比如我们想放入用户名,可以简单的创建一个Map然后put进去就可以了。

Map<String, Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, username());
</div>

解析也很简单,利用 jjwt 提供的parser传入秘钥,然后就可以解析token了。

Claims getClaimsFromToken(String token) {
 Claims claims;
 try {
 claims = Jwts.parser()
 .setSigningKey(secret)
 .parseClaimsJws(token)
 .getBody();
 } catch (Exception e) {
 claims = null;
 }
 return claims;
}
</div>

JWT本身没啥难度,但安全整体是一个比较复杂的事情,JWT只不过提供了一种基于token的请求验证机制。但我们的用户权限,对于API的权限划分、资源的权限划分,用户的验证等等都不是JWT负责的。也就是说,请求验证后,你是否有权限看对应的内容是由你的用户角色决定的。所以我们这里要利用Spring的一个子项目Spring Security来简化我们的工作。

Spring Security

Spring Security是一个基于Spring的通用安全框架,里面内容太多了,本文的主要目的也不是展开讲这个框架,而是如何利用Spring Security和JWT一起来完成API保护。所以关于Spring Secruity的基础内容或展开内容,请自行去官网学习( http://projects.spring.io/spring-security/ )。

简单的背景知识

如果你的系统有用户的概念的话,一般来说,你应该有一个用户表,最简单的用户表,应该有三列:Id,Username和Password,类似下表这种

而且不是所有用户都是一种角色,比如网站管理员、供应商、财务等等,这些角色和网站的直接用户需要的权限可能是不一样的。那么我们就需要一个角色表:

当然我们还需要一个可以将用户和角色关联起来建立映射关系的表。

这是典型的一个关系型数据库的用户角色的设计,由于我们要使用的MongoDB是一个文档型数据库,所以让我们重新审视一下这个结构。

这个数据结

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Spring Boot(四)之使用JWT和Spring Security保护REST API
  • Spring Boot(四)之使用JWT和Spring Security保护REST API

相关文章

  • 2017-05-28Java中Properties类的操作实例详解
  • 2017-05-28Java序列化和反序列化_动力节点Java学院整理
  • 2017-08-24react-apollo入门教程
  • 2017-05-28Spring boot集成Mybatis的方法教程
  • 2017-05-28java中Serializable接口作用详解
  • 2017-05-28浅析java中 Spring MVC 拦截器作用及其实现
  • 2017-05-28Java构造方法实例详解(动力节点java学院整理)
  • 2017-05-28Java栈之链式栈存储结构的实现代码
  • 2017-05-28java 实现文件夹的拷贝实例代码
  • 2017-05-28spring boot使用thymeleaf跳转页面实例代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Java基于正则表达式实现的替换匹配文本功能【经典实例】
    • Java 通过位运算求一个集合的所有子集方法
    • 详解Spring MVC事务配置
    • 详解spring面向切面aop拦截器
    • Java集合ArrayDeque类实例分析
    • Java中的大数类简单实现
    • Java Map 在put值时value值不被覆盖的解决办法
    • HashMap工作原理_动力节点Java学院整理
    • java 算法之归并排序详解及实现代码
    • 详解利用Spring的AbstractRoutingDataSource解决多数据源的问题

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有