Table of Contents
本記事では、“RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens” にて規定されている “Mutual-TLS certificate-bound access tokens” を利用するための、Authlete の設定手順を説明します。
“Mutual-TLS certificate-bound access tokens” は、「TLS クライアント認証」によるクライアント認証とは独立して動作します。「TLS クライアント認証」の設定については以下の記事をご参照ください。
“Mutual-TLS certificate-bound access tokens” の設定が有効化されている場合、Authlete の API は次の処理を行います。
/auth/introspection/standard API
これにより、相互 TLS によってクライアント証明書を提示できたクライアントのみが、そのアクセストークンの所持を証明し、API リクエストに利用できる(言い換えれば、他のクライアントが利用できない)ようになります。
Authlete のサービス管理者コンソール にログインし、 「トークン」タブの「アクセストークン」セクションにおいて以下を設定します。
項目 | 値 |
---|---|
TLS クライアント証明書を紐付けたアクセストークンのサポート | サポートする |
Authlete のクライアントアプリ開発者コンソール にアクセスし、 「基本情報」タブにおいて以下を設定します。
項目 | 値 |
---|---|
TLS クライアント証明書を紐付けたアクセストークンの使用 | 使用する |
以上により、“Mutual-TLS certificate-bound access tokens” が利用可能となります。
以下は設定後の、各 API の実行例です。(読みやすさのため折り返しています)
認可サーバーはクライアントとの相互 TLS 接続から得られたクライアント証明書を “clientCertificate” の値として指定し、Authlete にリクエストを送信します。
$ curl -s -X POST https://api.authlete.com/api/auth/token \
-u ...:... \
-H 'Content-type: application/json' \
-d '{'\
'"clientCertificate":"-----BEGIN CERTIFICATE-----\n
MIIDPDCCAiQCCQDfkemtGUyxAjANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJK\n
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM\n
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTIwMDUxMTEx\n
MDcyM1oXDTIxMDUxMTExMDcyM1owYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv\n
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV\n
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n
AQoCggEBAMu7V2QyQk4iLPry0OsykR/8WO2aNOBNoVZYDexF1TsFv9s2S4PEDFEt\n
1BZrEmBe5HWpGb1iuDGG6wjAanEkea8AIUgslMsOOB0rQnbJA3nI5wktjCG2VzWo\n
zrmxAAaBM7ixaLPcJT1K0FSu4fzse3X9gtA2rtNGwk1JEMNIBpFghxw7zzUZBduS\n
lkVPPcQ3gPGVutiWfNPNPAqb4eMKwtuTPXbZSJ4RO9xGKMIuoaBWO9xPS6rNy+Kr\n
vOckNEsR+8PBYh9vzbmF0mDlk+BMd9sOGyylYBARFdqukMJnSbVcRvr+Gcaf+QSg\n
FRHkVGWXHXtMRI+MsCvOXrhmlJhxbdMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\n
JfEyXTEGdjchre2dFCa/WLdH5PZBqB+E0Umm+/I+puA+aUpkRaOfmIUPNaCZ1Lgg\n
mOo8BGuEG0oXpOSBoRkxf46d1bxJk5YSe+TgSxS6YX/mE6Lt1Aj7HjojlCuNFGS6\n
vzyEugQSsOjuoIPS32PvqmZ+80jzVNUsMD76xGl32ZsVeJmDnogVPZ4NlolQcmH2\n
bYjK00uPXaUU30IVu+UTrEBhe30My/aW31NbT2I7Ct52wwu67pyP3QOKmuLxMd6N\n
+KkxfIY23zla4herq9vWZejgfBfkAwOapeIIHGYtY7IFxm6nqufb4h71vjeoouOt\n
31J7bEcAU9WRP1Pr/X4hLA==\n-----END CERTIFICATE-----\n",'\
'"parameters"':\
'"redirect_uri=https://client.example.org/cb/example.com'\
'&client_id=...'\
'&grant_type=authorization_code'\
'&code=smA...Gp4"'\
'}'
クライアント証明書に結びつけられたアクセストークンが発行されます。
{
"type": "tokenResponse",
"resultCode": "A050001",
"resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
"accessToken": "AHu...MMs"
, "accessTokenDuration": 86400,
"accessTokenExpiresAt": 1591935416474,
"action": "OK",
"clientId": 17566160603766,
"clientIdAliasUsed": false,
"grantType": "AUTHORIZATION_CODE",
"refreshToken": "_zkZeqy6pLdFerpwqJPh0S0gEZsSj9EbmwVsN92WNsE",
"refreshTokenDuration": 864000,
"refreshTokenExpiresAt": 1592713016474,
"responseContent": "{\"access_token\":\"AHu...MMs\",
\"refresh_token\":\"_zk...NsE\",
\"scope\":null,
\"token_type\":\"Bearer\",
\"expires_in\":86400}",
"subject": "testuser01"
}
JWT 形式のアクセストークンの場合には、以下のようなアクセストークンになります。
eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.
eyJzdWIiOiJ0ZXN0dXNlcjAxIiwic2NvcGUiOm51bGwsImlzcyI6Imh0dHBzOi8v
YXMuZXhhbXBsZS5jb20iLCJjbmYiOnsieDV0I1MyNTYiOiJPSURfU2MyeVJlVER4
OVFTN2YxU01Vek54c2g3a2hKWW1hSXdxWHc4WXV3In0sImV4cCI6MTU5MTkzOTMy
NiwiaWF0IjoxNTkxODUyOTI2LCJjbGllbnRfaWQiOiIxNzU2NjE2MDYwMzc2NiIs
Imp0aSI6InN6dDVnV0ZTb3ZGSVU1Ti13amRMeUZELUVpUzNyZEcyS1IzMTFCMkY2
RmMifQ.
Pw3IntOrXDqW3Z5eoGSeeJaPG5n1aKEVokgbUh_BJpqzuZ6F6GDDLhj98XBvjii
x9oAmaTpy39ijl1vcq3r1BA
このアクセストークンのペイロード部には、以下のように、証明書のサムプリントが含まれます。
{
"sub": "testuser01",
"scope": null,
"iss": "https://as.example.com",
"cnf": {
"x5t#S256": "OID\_Sc2yReTDx9QS7f1SMUzNxsh7khJYmaIwqXw8Yuw"
},
"exp": 1591939326,
"iat": 1591852926,
"client_id": "17566160603766",
"jti": "szt5gWFSovFIU5N-wjdLyFD-EiS3rdG2KR311B2F6Fc"
}
リソースサーバーはクライアントとの相互 TLS 接続から得られたクライアント証明書を “clientCertificate” の値として指定し、Authlete にリクエストを送信します。
curl -s -X POST https://api.authlete.com/api/auth/introspection \
-u ...:... \
-H 'Content-type: application/json' \
-d '{
"token": "AHu...MMs",
"clientCertificate": "-----BEGIN CERTIFICATE-----\n
MIIDPDCCAiQCCQDfkemtGUyxAjANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJK\n
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM\n
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTIwMDUxMTEx\n
MDcyM1oXDTIxMDUxMTExMDcyM1owYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv\n
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV\n
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n
AQoCggEBAMu7V2QyQk4iLPry0OsykR/8WO2aNOBNoVZYDexF1TsFv9s2S4PEDFEt\n
1BZrEmBe5HWpGb1iuDGG6wjAanEkea8AIUgslMsOOB0rQnbJA3nI5wktjCG2VzWo\n
zrmxAAaBM7ixaLPcJT1K0FSu4fzse3X9gtA2rtNGwk1JEMNIBpFghxw7zzUZBduS\n
lkVPPcQ3gPGVutiWfNPNPAqb4eMKwtuTPXbZSJ4RO9xGKMIuoaBWO9xPS6rNy+Kr\n
vOckNEsR+8PBYh9vzbmF0mDlk+BMd9sOGyylYBARFdqukMJnSbVcRvr+Gcaf+QSg\n
FRHkVGWXHXtMRI+MsCvOXrhmlJhxbdMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\n
JfEyXTEGdjchre2dFCa/WLdH5PZBqB+E0Umm+/I+puA+aUpkRaOfmIUPNaCZ1Lgg\n
mOo8BGuEG0oXpOSBoRkxf46d1bxJk5YSe+TgSxS6YX/mE6Lt1Aj7HjojlCuNFGS6\n
vzyEugQSsOjuoIPS32PvqmZ+80jzVNUsMD76xGl32ZsVeJmDnogVPZ4NlolQcmH2\n
bYjK00uPXaUU30IVu+UTrEBhe30My/aW31NbT2I7Ct52wwu67pyP3QOKmuLxMd6N\n
+KkxfIY23zla4herq9vWZejgfBfkAwOapeIIHGYtY7IFxm6nqufb4h71vjeoouOt\n
31J7bEcAU9WRP1Pr/X4hLA==\n-----END CERTIFICATE-----"
}'
}'
アクセストークン (token) とクライアント証明書 (clientCertificate) の結びつきが確認できた場合には、以下のようなレスポンスが返却されます。このレスポンスには、クライアント証明書のサムプリント(certificateThumbprint) が含まれています。
{
"type": "introspectionResponse",
"resultCode": "A056001",
"resultMessage": "[A056001] The access token is valid.",
"action": "OK",
"certificateThumbprint": "OID_Sc2yReTDx9QS7f1SMUzNxsh7khJYmaIwqXw8Yuw",
"clientId": ...,
"clientIdAliasUsed": false,
"existent": true,
"expiresAt": 1591936228000,
"refreshable": true,
"responseContent": "Bearer error=\"invalid_request\"",
"subject": "testuser01",
"sufficient": true,
"usable": true
}
リソースサーバーは認可サーバーのトークンイントロスペクションエンドポイントに、対象のアクセストークンを送信します。認可サーバーはそのリクエスト内容を Authlete に転送します。
$ curl -s -X POST https://api.authlete.com/api/auth/introspection/standard \
-u ...:... \
-H 'Content-type: application/json' \
-d '{ "parameters":"token=AHu...MMs
" }'
アクセストークンに結びつくクライアント証明書が確認できた場合には、Authlete はその証明書のサムプリントを含む responseContent を返却します。認可サーバーはこの responseContent をリソースサーバーに、トークンイントロスペクションエンドポイントからのレスポンスとして返却します。
{
"type": "standardIntrospectionResponse",
"resultCode": "A145001",
"resultMessage": "[A145001] Introspection was performed successfully (type=access_token, active=true).",
"action": "OK",
"responseContent": {
"sub": "testuser01",
"scope": null,
"iss": "https://as.example.com",
"active": true,
"cnf": {
"x5t#S256": "OID_Sc2yReTDx9QS7f1SMUzNxsh7khJYmaIwqXw8Yuw"
},
"token_type": "Bearer",
"exp": 1591936228,
"client_id": "17566160603766"
}
}