オンラインの研究 - 16日目 - 講義 - 春のセキュリティのOAuth2 JWT 5

3.4のOAuth2 パスワードモード認証 
パスワードモード(リソース所有者のパスワードの資格情報の差)アプリケーショントークンの認証コードとモードは、もはや認証コードを使用していませんが、直接されたトークンを申請するユーザー名とパスワードによる。
テストは次の通りです:ポスト要求:HTTP:// localhostを:40400 / AUTH / OAuthのトークン/
パラメータ: 
grant_type :でパスワードモードの許可フィルパスワード 
ユーザ名:アカウントの 
パスワード:パスワード 
と、このリンクを使用する必要が  HTTP基本認証を。
 
3.5 トークン検証 
春のセキュリティのOAuth2を提供し、エンドポイントの検証トークン、次のように: 
取得:  HTTP:// localhostを:40400 / AUTH / OAuthの/ check_tokenトークン=? 
パラメータ: 
トークン:トークン 
使用の郵便配達のテストは、次のように:

 
EXP :期限切れを時間、ロングタイプ、距離1970 秒で(新新A日付()ザgetTime()がから現在の時刻を取得し、1970 ミリ秒年)。 
USER_NAME :ユーザー名が 
CLIENT_ID :クライアント同上、にoauth_client_details 設定 
範囲:クライアントの適用範囲を、中oauth_client_detailsの構成テーブル 
JTI :トークン固有の識別に対応する 
企業ID UserPic 名前uType ID :これらのフィールドは、認証サービスです春のセキュリティ、ユーザ識別情報に基づいて延長 
3.5 リフレッシュトークン 
トークンの有効期限が切れるしたときにトークンを再生成することで、認証コードとパスワード認証を生成するために、許可トークンと異なるリフレッシュトークン、認証コードは、リフレッシュトークンには必要ありません。 
アカウントとパスワードを必要としない、あなただけのリフレッシュトークン、クライアントの必要ID とパスワードクライアントを。 
次のようにテストは以下のとおりです。 
ポストHTTP:// localhostを:40400 / AUTH / OAuthのトークン/ 
パラメータ:

 
3.6 JWTの研究 
JWTは3.6.1 導入 
導入にJWT :以下のように、伝統的な検証トークン方法を見る前に
 

、ユーザーごとに許可されている伝統的な方法で問題時間は、リソース・サービスを要求し、リソースは、トークンの正当性を確認するための認証サービスにアクセスするためのトークンサービスを実行する必要があり、根はユーザーのトークン、貧弱な性能を得るために、関連情報によります。
解決策: 
使用JWTのアイデアは、ユーザーがで認証を取得することをされたJWTのトークン、JWT のトークンは、クライアントがのみ持参する必要があり、ユーザ関連情報に含まれていJWTの完全な注文に、独自のアルゴリズムの事前の合意に基づいて、リソースやサービス、リソースやサービスへのアクセスをすべての要求の認証サービス認証を完了する必要がなく、カードを確認してください。
JWT の下に示すように、トークンの承認プロセス: 

 
どのようなものですJWTは? 
ウェブトークンJSON JWT )オープンな業界標準である(RFC 7519 のプロファイルを定義する)、のための自己完結型のプロトコル形式の通信は、双方に送信されるJSONのデジタル署名を通過し、情報オブジェクトを検証することができると信頼。JWT HMAC アルゴリズムまたはRSA パブリックキー/ 署名のための秘密鍵のペア、改ざんを防止。
公式サイト:https://jwt.io/ 
標準:https://tools.ietf.org/html/rfc7519 
JWTの利点トークン: 
。1 JWT をもとにJSONは、解析は非常に便利です。 
2は、あなたが簡単に拡張するために、トークンの豊富なコンテンツでカスタマイズすることができます。 
図3は、非対称暗号化アルゴリズムおよびデジタル署名技術により、JWTは、改ざんの安全性を防ぎます。 
4 、リソースサービスは使用していますJWTは、承認を完了するために、認証サービスを依存していません。 
短所: 
1は、JWT 長いトークンは、ストレージ容量が比較的大きい占めます。

3.6.1.1  トークン構造 
学習によってJWT カスタムトークン構造は、JWT の基礎を築くためにトークン。 
JWTトークンは、3つの部分、使用の中点(各部分から成る例えばパーティション):xxxxx.yyyyy.zzzzz 
ヘッダ 
ヘッドは、トークンタイプ(すなわち、含むJWT )及び(例えばの使用などのハッシュアルゴリズムHMAC SHA256 またはRSA ) 
Aを以下のような例は次のとおり 
以下であるヘッダコンテンツ部分

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

コンテンツ利用の上部Base64Urlの符号化は、文字列が取得されるJWT トークンの第1の部分を。 
ペイロード 
第2の部分は、負荷だけでなく、コンテンツであるJSONの有効な情報を格納する場所であるオブジェクトは、格納することができるJWT 準備されたフィールド、比 
:としてISS (発行者)、EXP (満了タイムスタンプ)、小(指向を利用者)などが、また、カスタムフィールドすることができます。 
このセクションでは、オリジナルのコンテンツを復元デコードすることができますので、このセクションでは、機密情報を保存することは推奨されません。 
最後に、使用負荷の第二の部分Base64Urlの符号化は、文字列が取得されるJWT トークンの第2の部分を。 
例:

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

Signature 
第三部分是签名,此部分用于防止jwt内容被篡改。 
这个部分使用base64url将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声明 
签名算法进行签名。 
一个例子:

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

base64UrlEncode(header)jwt令牌的第一部分。 
base64UrlEncode(payload)jwt令牌的第二部分。 
secret:签名所使用的密钥。 
3.6.3 JWT入门 
Spring Security 提供对JWT的支持,本节我们使用Spring Security 提供的JwtHelper来创建JWT令牌,校验JWT令牌 
等操作。 
3.6.3.1 生成私钥和公钥 
JWT令牌生成采用非对称加密算法 
1、生成密钥证书 
下边命令生成密钥证书,采用RSA 算法每个证书包含公钥和私钥 
keytool -genkeypair -alias xckey -keyalg RSA -keypass xuecheng -keystore xc.keystore -storepass 
xuechengkeystore 
Keytool 是一个java提供的证书管理工具 
-alias:密钥的别名 
-keyalg:使用的hash算法 
-keypass:密钥的访问密码 
-keystore:密钥库文件名,xc.keystore保存了生成的证书 
-storepass:密钥库的访问密码 
查询证书信息: 
keytool -list -keystore xc.keystore 
删除别名 
keytool -delete -alias xckey -keystore xc.keystore 
2、导出公钥 
openssl是一个加解密工具包,这里使用openssl来导出公钥信息。 
安装 opensslhttp://slproweb.com/products/Win32OpenSSL.html 
安装资料目录下的Win64OpenSSL-1_1_0g.exe 
配置opensslpath环境变量,本教程配置在D:\OpenSSL-Win64\bin 
cmd进入xc.keystore文件所在目录执行如下命令:

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



3.6.3.2 生成jwt令牌 
在认证工程创建测试类,测试jwt令牌的生成与验证。

//生成一个jwt令牌
@Test
public void testCreateJwt(){
//证书文件
String key_location = "xc.keystore";
//密钥库密码
String keystore_password = "xuechengkeystore";
//访问证书路径
ClassPathResource resource = new ClassPathResource(key_location);
//密钥工厂
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,
keystore_password.toCharArray());
//密钥的密码,此密码和别名要匹配
String keypassword = "xuecheng";
//密钥别名
String alias = "xckey";
//密钥对(密钥和公钥)
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypassword.toCharArray());
//私钥
RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
//定义payload信息
Map<String, Object> tokenMap = new HashMap<>();
tokenMap.put("id", "123");
tokenMap.put("name", "mrt");
tokenMap.put("roles", "r01,r02");
tokenMap.put("ext", "1");
//生成jwt令牌
Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), new RsaSigner(aPrivate));
//取出jwt令牌
String token = jwt.getEncoded();
System.out.println("token="+token);
}

3.6.3.3 验证jwt令牌

//资源服务使用公钥验证jwt的合法性,并对jwt解码
@Test
public void testVerify(){
//jwt令牌
String token
="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHQiOiIxIiwicm9sZXMiOiJyMDEscjAyIiwibmFtZSI6Im1ydCIsI
mlkIjoiMTIzIn0.KK7_67N5d1Dthd1PgDHMsbi0UlmjGRcm_XJUUwseJ2eZyJJWoPP2IcEZgAU3tUaaKEHUf9wSRwaDgwhrw
fyIcSHbs8oy3zOQEL8j5AOjzBBs7vnRmB7DbSaQD7eJiQVJOXO1QpdmEFgjhc_IBCVTJCVWgZw60IEW1_Lg5tqaLvCiIl26K
48pJB5f‐le2zgYMzqR1L2LyTFkq39rG57VOqqSCi3dapsZQd4ctq95SJCXgGdrUDWtD52rp5o6_0uq‐
mrbRdRxkrQfsa1j8C5IW2‐T4eUmiN3f9wF9JxUK1__XC1OQkOn‐ZTBCdqwWIygDFbU7sf6KzfHJTm5vfjp6NIA";
//公钥
String publickey = "‐‐‐‐‐BEGIN PUBLIC KEY‐‐‐‐‐
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAijyxMdq4S6L1Af1rtB8SjCZHNgsQG8JTfGy55eYvzG0B/E4AudR2
prSRBvF7NYPL47scRCNPgLnvbQczBHbBug6uOr78qnWsYxHlW6Aa5dI5NsmOD4DLtSw8eX0hFyK5Fj6ScYOSFBz9cd1nNTvx
2+oIv0lJDcpQdQhsfgsEr1ntvWterZt/8r7xNN83gHYuZ6TM5MYvjQNBc5qC7Krs9wM7UoQuL+s0X6RlOib7/mcLn/lFLsLD
dYQAZkSDx/6+t+1oHdMarChIPYT1sx9Dwj2j2mvFNDTKKKKAq0cv14Vrhz67Vjmz2yMJePDqUi0JYS2r0iIo7n8vN7s83v5u
OQIDAQAB‐‐‐‐‐END PUBLIC KEY‐‐‐‐‐";
//校验jwt
Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(publickey));
//获取jwt原始内容
String claims = jwt.getClaims();
//jwt令牌
String encoded = jwt.getEncoded();
System.out.println(encoded);
}

 

发布了835 篇原创文章 · 获赞 152 · 访问量 14万+

おすすめ

転載: blog.csdn.net/qq_40208605/article/details/104393315