16、Spring Security Oauth2 JWT(二)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 用户身份认证:用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问。常见的用户身份认证表现形式有:用户名密码登录,指纹打卡等方式。

校验令牌

Get: http://localhost:40400/auth/oauth/check_token?token=

响应结果:

该 接 口 请 求 会 重 新 调 用 U s e r D e t a i l s S e r v i c e I m p l 类 中 的 l o a d U s e r B y U s e r n a m e 方 法 。 \color{#FF0000}{该接口请求会重新调用UserDetailsServiceImpl类中的loadUserByUsername方法。}该接口请求会重新调用UserDetailsServiceImpl类中的loadUserByUsername方法。


刷新令牌

刷新令牌是当令牌快过期时重新生成一个令牌,它和授权码跟密码模式生成令牌不同,刷新令牌是取授权码跟密码模式生成的令牌结果集重新生成一个令牌,只需要一个刷新令牌、客户端id和客户端密码。

Post:http://localhost:40400/auth/oauth/token

参数:

grant_type: 固定为 refresh_token

refresh_token:填写申请令牌中的refresh_token字段值

刷新令牌成功,会重新生成新的访问令牌和刷新令牌,令牌的有效期也比旧令牌长。

刷新令牌通常是在令牌快过期时进行刷新,让客户登录时间延长,不用让用户重新登录。


JWT研究

传统授权方法的问题是用户每次请求资 源 服 务 \color{#FF0000}{资源服务}资源服务,资源服务都需要携带令牌访问认 证 服 务 \color{#FF0000}{认证服务}认证服务去校验令牌的合法性,并根据令牌获取用户的相关信息,性能低下。

使用JWT的思路是,用户认证通过会得到一个JWT令牌,JWT令牌中已经包括了用户相关的信息,客户端只需要携带JWT访问资源服务,资源服务根据事先约定的算法自行完成令牌校验,无需每次都请求认证服务完成授权。

J W T 令 牌 就 是 为 了 解 决 不 用 每 次 请 求 认 证 服 务 完 成 授 权 。 \color{#FF0000}{JWT令牌就是为了解决不用每次请求认证服务完成授权。}JWT令牌就是为了解决不用每次请求认证服务完成授权。

JWT令牌授权过程如下图:

什么是JWT?

JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简洁的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公钥/私钥对来签名,防止被篡改。

JWT令牌的优点:

1、JWT基于json,非常方便解析。

2、可以在令牌中自定义丰富的内容,易扩展。

3、通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。

4、资源服务使用JWT可不依赖认证服务即可完成授权。

缺点:令牌较长,存储空间比较大


令牌结构

通过学习JWT令牌结构为自定义JWT令牌打好基础。

JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz

1、Header

包括令牌的类型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA)

例如:

{ 
"alg": "HS256", 
"typ": "JWT" 
}

将上边的内容使用Base64Url编码,得到一个字符串就是JWT令牌的第一部分。

2、Payload

第二部分是负载,内容也是一个json对象,它是存放有效信息的地方,它可以存放jwt提供的现成字段,比 如:iss(签发者),exp(过期时间戳), sub(面向的用户)等,也可自定义字段。

此部分不建议存放敏感信息,因为此部分可以解码还原原始内容。

最后将第二部分负载使用Base64Url编码,得到一个字符串就是JWT令牌的第二部分。

{ 
"sub": "1234567890", 
"name": "456", 
"admin": true 
}

3、Signature

第三部分是签名,此部分用于防止jwt内容被篡改。

这个部分使用base64url将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声明 签名算法进行签名。

HMACSHA256( 
base64UrlEncode(header) + "." + base64UrlEncode(payload), 
secret)

base64UrlEncode(header):jwt令牌的第一部分。

base64UrlEncode(payload):jwt令牌的第二部分。

secret:签名所使用的密钥。


JWT入门

本节我们使用Spring Security 提供的JwtHelper来创建JWT令牌,校验JWT令牌等操作。

生成私钥和公钥

JWT令牌生成采用非对称加密算法


1、生成密钥证书

下边命令生成密钥证书,采用RSA 算法每个证书包含公钥和私钥

keytool -genkeypair -alias xckey -keyalg RSA -keypass xuecheng -keystore xc.keystore -storepass xuechengkeystore

在桌面创建文件夹jwt,cmd进入该目录,输入上面指令:

查询证书信息: keytool -list -keystore xc.keystore

口令输入:xuechengkeystore

删除别名:keytool -delete -alias xckey -keystore xc.keystore


2、导出公钥

openssl是一个加解密工具包,这里使用openssl来导出公钥信息。

安装 openssl:http://slproweb.com/products/Win32OpenSSL.html

配置openssl的path环境变量,本教程配置在D:\Soft\OpenSSL-Win64\bin

cmd进入xc.keystore文件所在目录执行如下命令:

keytool ‐list ‐rfc ‐‐keystore xc.keystore | openssl x509 ‐inform pem ‐pubkey

将上边的公钥拷贝到文本文件中,合并为一行放到publickey.txt文件中。


1、生成jwt令牌

执行TestJwt类中的testCreateJwt方法生成密钥:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoieGh5In0.Y5wtZJAlirAMtQ2qQaNehDDa1uBhHWjJAHeNBXYcKP48rYpdM--oMGXZJgMa56HgXJ29YUtdKJstO8NUqJXLp7GkUvXWDBwhvmlyT82Vci7pwJitgO6YCBaYcXOSUFmWHxDX6o5RrJ0ivfU0nBE07FX30k0eBvDYnxH5FVRqo19WMBR9a36bHcYBrj9ZWsinbOmMUCgLMkNnteXHXPPH7PqTTpAmn_8C5cGQS8ER3CXXlSmRrGSn8uoYQKV87W_x7mapu6lb7vYLgVyBTOH2jUduOYg7rOD4S5JC7XJFvuyEH4z1Mew1k5NqoBBx5dhsRDJFANxoqvQpIlDbwJ1gzg

2、验证jwt令牌

执行TestJwt类中的testVerify方法进行校验

校验成功返回令牌的名字:


认证接口开发

用户登录的流程图如下:


Redis配置

1、安装Redis服务

2、安装redis-desktop-manager客户端

pom文件中添加redis

3、redis连接配置

在xc-service-ucenter-auth工程的yml文件中配置如下:

spring:
  application:
    name: xc-service-ucenter-auth
  redis:
    host: ${REDIS_HOST:127.0.0.1}
    port: ${REDIS_PORT:6379}
    timeout: 5000 #连接超时 毫秒
    jedis:
      pool:
        maxActive: 3
        maxIdle: 3
        minIdle: 1
        maxWait: -1 #连接池最大等行时间 -1没有限制

4、测试

执行RedisTest类中的testRedis方法:

返回结果,说明执行成功:


认证服务

1、登录接口

前端post提交账号、密码等,用户身份校验通过,生成令牌,并将令牌存储到redis。 将令牌写入cookie。

2、退出接口

校验当前用户的身份是否合法并且为已登录状态。 将令牌从redis删除。 删除cookie中的令牌。

流程:

1、api中的方法:

在AuthControllerApi类中添加login和logout方法;

2、yml文件中配置:

auth:
  tokenValiditySeconds: 1200  #token存储到redis的过期时间
  clientId: XcWebApp
  clientSecret: XcWebApp
  cookieDomain: xuecheng.com
  cookieMaxAge: -1

3、申请令牌

为了不破坏Spring Security的代码,我们在Service方法中通过RestTemplate请求Spring Security所暴露的申请令牌接口来申请令牌。

执行TestClient类中的testClient方法测试;

4、Dao

暂时使用静态数据,待用户登录调通再连接数据库校验用户信息。

5、Service

调用认证服务申请令牌,并将令牌存储到 redis。

1、AuthToken

创建 AuthToken模型类,存储申请的令牌,包括身份令牌、刷新令牌、jwt令牌

身份令牌:用于校验用户是否认证

刷新令牌:jwt令牌快过期时执行刷新令牌

JWT令牌:用于授权。

6、Controller

在AuthController中添加、saveCookie、logout方法

登录url放行

认证服务默认都要校验用户的身份信息,这里需要将登录url放行

在WebSecurityConfig类中重写 configure(WebSecurity web)方法,如下:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/userlogin","/userlogout","/userjwt");
}

测试认证接口:

Post请求:http://localhost:40400/auth/userlogin

测试结果:


测试写入Cookie

cookie最终会写到xuecheng.com域名下,可通过nginx代理进行认证,测试cookie是否写成功。

1、配置nginx代理

在server中添加配置代理路径:

#认证
location ^~ /openapi/auth/ { 
  proxy_pass http://auth_server_pool/auth/;
}

添加:

#认证服务
upstream auth_server_pool{
  server 127.0.0.1:40400 weight=10;
}

POST:http://ucenter.xuecheng.com/openapi/auth/userlogin

观察cookie写入结果:

这个value就是返回值返回的短令牌

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
463 5
|
6月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
332 0
|
4月前
|
JSON 安全 算法
|
1月前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
346 12
|
3月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
108 8
|
4月前
|
存储 安全 Java
|
3月前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
90 0
|
5月前
|
安全 Java 数据安全/隐私保护
|
6月前
|
NoSQL 关系型数据库 MySQL
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
210 2
|
6月前
|
Java Spring 安全
Spring 框架邂逅 OAuth2:解锁现代应用安全认证的秘密武器,你准备好迎接变革了吗?
【8月更文挑战第31天】现代化应用的安全性至关重要,OAuth2 作为实现认证和授权的标准协议之一,被广泛采用。Spring 框架通过 Spring Security 提供了强大的 OAuth2 支持,简化了集成过程。本文将通过问答形式详细介绍如何在 Spring 应用中集成 OAuth2,包括 OAuth2 的基本概念、集成步骤及资源服务器保护方法。首先,需要在项目中添加 `spring-security-oauth2-client` 和 `spring-security-oauth2-resource-server` 依赖。
77 0