signature=82c2684cc7c94545614b750164c2561d,第八章 SpringCloud Oauth2认证中心-基于JWT认证

本文探讨了在现代web架构中,如何使用JWT(JSON Web Token)替代传统cookie和session机制,特别是在OAuth2服务器端的授权流程。详细介绍了JWT的构成、生成过程,并展示了如何在Spring Cloud OAuth2环境中使用JWT。重点在于解析access_token并展示其中包含的用户信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.项目概要

传统的web应用中,我们通常通过cookie+session机制来保证调用的安全,在没有认证的情况下自动重定向到登录页面或者调用失败页面,而现在整个架构编程微服务模式了,cookie和session机制已经不能很好的满足保护API的需求了,更多的情况下采用token的验证机制,JWT的本质也是一种token。

JWT:JSON Web Token,是JSON风格的轻量级授权和认证规范,可以实现无状态,分布式的web应用授权。JWT的内容由三部分组成,分别是Header,Payload,Signature,三个部分之间通过.分割,举例

xxxxx.yyyyyy.zzzzz

Header

头部Header一般由2个部分组成alg和typ,alg是加密算法,如HMAC或SHA256,typ是token类型,取值为jwt,一个Header的例子

{

"alg": "HS256",

"typ": "JWT"

}

然后对Header部分进行Base64编码,得到第一部分的值

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{PAYLOAD}.{SIGNATURE}

Payload

内容部分Payload是JWT存储信息的主体,包含三类内容

标准中注册的声明

公共的声明

私有的声明

标准中注册的声明

iss:jwt签发者

sub:jwt所面向的用户

aud:接收jwt的一方

exp:jwt的过期时间

nbf:定义在什么时间之前该jwt是不可用的

iat:jwt的签发时间

jti:jwt的唯一标识,主要用作一次性token,避免重放攻击

公共的声明:

可以存放任何信息,根据业务实际需要添加,如用户id,名称等,但不要存放敏感信息

私有的声明:

私有声是提供者和消费者所共同定义的声明,不建议存放敏感信息

举例:定义一个payload:

{ "sub": "1234567890", "name": "John Doe", "admin": true }对其进行Base64编码,得到第二部分

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.{SIGNATURE}

Signature

token的签名部分由三部分组成256签名

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret');

得到最终的token串

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

2.Oauth2-Server中生成JWT Token

a)通过keytool生成证书

keytool -genkeypair -alias kevin_key -keyalg RSA -keypass 123456 -keystore kevin_key.jks -storepass 123456

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

查看证书信息:

keytool -list -v -keystore kevin_key.jks -storepass 123456

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

查看公钥信息

keytool -list -rfc -keystore kevin_key.jks -storepass 123456

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

b)将生成的kevin_key.jks文件放到oauth2-server工程的srce/main/resources目录下

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

c)添加jwt相关jar包依赖

org.springframework.security

spring-security-jwt

d)在OAuth2服务器端配置核心类AuthorizationServerConfiguration中增加jwt token相关配置

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

3.测试Oauth2服务

出现登录页面,输入用户名:admin 密码;123456

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

点击Submit按钮,进入用户授权确认页面

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

点击Approve,跳转到baidu页面,后面携带了code和state参数

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

根据code换取access_code,注意使用post方法

注意这个code要和上个步骤中获得的code保持一致

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

用户名输入client,密码是secret,点击确定,可以看到access_token已经是jwt格式的字符了

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

{"access_token":"

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTAxNzQ2MDYsInVzZXJfbmFtZSI6ImFkbWluIiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiNTJhOGM5MTUtMTE2OS00YzU5LWI0MmEtZGY4ZDM0Y2QwZWU0IiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsiYXBwIl19.GecJM-FHApwznyYl-D3IjB0TpjhdhUXfYv782kfS9vdT0VZsu2HN-MGb-N-6Hf0efZ_mmz54IahJaq3KTw251v4L2O5A1r_iMuUP7GXs_qPHAGn3K1b4l-mNnpJdH5hhS5zYIRqOX2a8DXyI4zD7g8BQL-9PiR3kj9k_z9nW8vY9l2_x5Kyoc-sehxxQ5uQHM3xu6DzOwBpbbER7U_NnUwmcz5nS9YyAexSDnBbZAVpQavL2s1yYQVMJ5Dreq2asXHFbeQHXu5UqVbbTFuOgAylbFJ9K-3nsGAKT9NbzqBPRovI3s_X9HgjrzJHAuojBMeK0QMbvYSbUg2HB7MNNJw","token_type":"bearer","expires_in":43199,"scope":"app","user_name":"admin","jti":"52a8c915-1169-4c59-b42a-df8d34cd0ee4"}

4.access_token信息解析

我们通过上个步骤得到的token信息是不可读的,但是因为header,body都是经过base64转码过的,因此我们可以通过Base64将其解码,spring cloud里也提供了jwt相关的工具类帮我们来反解析这个串

package com.pachiraframework.springcloud.oauth2.config;

import org.junit.Test;

import org.springframework.security.jwt.Jwt;

import org.springframework.security.jwt.JwtHelper;

public class JwtTest {

@Test

public void test() {

String token = "

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTAxNzQ2MDYsInVzZXJfbmFtZSI6ImFkbWluIiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiNTJhOGM5MTUtMTE2OS00YzU5LWI0MmEtZGY4ZDM0Y2QwZWU0IiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsiYXBwIl19.GecJM-FHApwznyYl-D3IjB0TpjhdhUXfYv782kfS9vdT0VZsu2HN-MGb-N-6Hf0efZ_mmz54IahJaq3KTw251v4L2O5A1r_iMuUP7GXs_qPHAGn3K1b4l-mNnpJdH5hhS5zYIRqOX2a8DXyI4zD7g8BQL-9PiR3kj9k_z9nW8vY9l2_x5Kyoc-sehxxQ5uQHM3xu6DzOwBpbbER7U_NnUwmcz5nS9YyAexSDnBbZAVpQavL2s1yYQVMJ5Dreq2asXHFbeQHXu5UqVbbTFuOgAylbFJ9K-3nsGAKT9NbzqBPRovI3s_X9HgjrzJHAuojBMeK0QMbvYSbUg2HB7MNNJw";

Jwt jwt = JwtHelper.decode(token);

System.out.println(jwt.toString());

}

}

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

通过这个测试我们可以看出来,token中已经包含了当前用户的信息了,包括我们在accessTokenConvertor()方法中给token中添加的额外信息user_name

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值