Service Account認証 (JWT)
Service Account認証とは、アプリ専用の仮想管理者アカウントを使用して認証を行い、Access Tokenを発行してAPIを利用する方法です。
Service Account認証では、Json Web Token (以降、JWT)を使用してAccess Tokenを発行します。
Developers Consoleに登録したアプリのService Account認証 (JWT)を使用したAccess Tokenを発行するフローは以下の通りです。
- アプリ開発者は、Developer ConsoleよりService Accountを発行する
- アプリは、Service Accountを使用してJWT生成する(RFC-7519)
- アプリは、JWTを電子署名する (signature) (RFC-7515)
- アプリは、LINE WORKSにAccess Tokenの発行を要求する (RFC-7523)
- アプリは、Access Tokenの有効期限が過ぎた場合、Refresh Tokenをもとに再発行する
Access Token / Refresh Token の制限について
Access Token
- 有効期限: 24時間
Refresh Token
- 有効期限: 90日
Service Accountについて
LINE WORKS API 2.0を利用するにはユーザーによる認証を行う必要があります。
組織連携や安否確認などのユーザーの認証を必要としないアプリを提供するには、Service Accountを利用して認証を行います。 Service Accountは、Developers Console のアプリ設定で発行可能です。
発行したService Accountのメンバー情報は以下のように表示されます。
- 姓 : [SERVICE]
- 名 : アプリ名
- ID : {発行したService Account}@domain
Service Account 特徴
- 1つのアプリは1つのService Accountを発行可能
- 発行と同時に管理者権限が付与され、管理者にサービス通知される
- 発行元のアプリ以外では使用できない
- アプリ専用の仮想管理者アカウントであるため課金対象にならない
- 使用できないAPIがある
- Path パラメータの userId に対して、me を使用できない
事前準備
Developers Consoleにアプリを登録し、以下のアプリ情報を準備します。
- Client ID
- Client Secret
- Service Account
- Private Key
JWTの生成
JWTは以下の形式を使用してください。
{header BASE64エンコード}.{JSON Claim set BASE64エンコード}.{signature BASE64エンコード}
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9
.eyJpc3MiOiI0NmM0ZjI4MWY4MTE0OGM5Yjg0NmM1OTI2MmFlNTg4OCIsImlhdCI6MTQ5MjUwNDY3MiwiZXhwIjoxNDkyNTA2NDcyfQ
.aICZ8qvYFKSJT6VdrmEcs6siCHaCgFkqpVs5VALKhf98sZjguppp-bOy9MpNlNepfSF0IyrdG3JavHLUYBz1NEVVZJwEm39f7gODmnt-_kGfDo1YtOqnclP1gM8oiObF2AH2Eneh3XuyeVeZbKAZmp6I_ZOf8AGayVVui61CsDPbUIPZSKUnbW1-vlXboTlojxJhvHznpYSNanHSrg5Nht2VO5sOeclEgPqg3J8Y6XOT60u8Morv5wHUy8a0QyO0yWCT5OJdXeVj94qfDAM15a1Puw9PfQOPm7QhOarvCJ8cOSqo9PHluq9-KZ1WXmfxSo-_itTb8y2YRT3kd21maQ
headerにてRSA SHA-256アルゴリズムを明示します。
{"alg":"RS256","typ":"JWT"}
この値をBASE64エンコードすると以下のようになります。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
JSON Claim setの情報は以下の通りです。
パラメータ | 説明 |
---|---|
iss | アプリのClient ID |
sub | Service Account ID |
iat | JWT生成日時。UNIX時間で指定(単位:sec) |
exp | JWT満了日時。UNIX時間で指定(単位:sec) |
例) 以下の条件の場合
- Client ID: ZbsOq6zjt0IhtZZnrc
- Service Account: 1wagx.serviceaccount@example.com
- JWT生成日時: 2021-06-03 15:29:18
- JWT満了日時: 2021-06-03 16:29:18 (60分後満了)
JSON形式での表示
{
"iss":"ZbsOq6zjt0IhtZZnrc",
"sub":"1wagx.serviceaccount@example.com",
"iat":1634711358,
"exp":1634714958
}
この値をBASE64エンコードすると、以下のようになります。
eyJpc3MiOiJhYmNkIiwic3ViIjoiNDZjNGYyODFmODExNDhjOWI4NDZjNTkyNjJhZTU4ODhAZXhhbXBsZS5jb20iLCJpYXQiOjE2MzQ3MTEzNTgsImV4cCI6MTYzNDcxNDk1OH0
headerとClaim setを「.」で組み合わせると{header BASE64エンコード}.{JSON Claim set BASE64エンコード}は以下のようになります。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoiNDZjNGYyODFmODExNDhjOWI4NDZjNTkyNjJhZTU4ODhAZXhhbXBsZS5jb20iLCJpYXQiOjE2MzQ3MTEzNTgsImV4cCI6MTYzNDcxNDk1OH0
JWT電子署名(signature)
電子署名はJWS(JSON Web Signature RFC-7515)規約を遵守します。
先に生成したJWT headerとbodyのbyte arrayを、Developer Consoleでダウンロードした認証キーを用いて RSA SHA-256アルゴリズム(headerで定めたRS256)で暗号化し、BASE64エンコードします。
上記で生成した{header BASE64エンコード}.{JSON Claim set BASE64エンコード}を電子署名して、BASE64エンコードすると{signature BASE64エンコード}は以下のようになります。
RqOaErJWZc_ZGijL5r0a892NnQL_zbkgchThW3j4pzG_qMqtOgex2odEs8JFsPfQ2c8_2BkaUMckNIN3C27t2RsbppJYl3nQr9w2Jb6x9LJR1Ym3pJVlpRvarracRwa00OgVc0mZ5dkn3B4I55GpKjZ3oOLfW7Xw0OAj8fEYCmWJmma3xQQrScJAUqN-jTZ7T3C6-ieVo3IhTRopzS5cru3ilQWekQ6-fRTPr8W4EV9B0u8wXhCxT90mlAYtebPvyovpPTNhi8Oq8rO_gVnpSMNkDtZ6p6OpC7_XG7ZcjUo7KRCxyPLe2-TmeWtV0jL5vqsjnlAznKtw5mPGOwpjVQ
最終的に完成したJWT{header BASE64エンコード}.{JSON Claim set BASE64エンコード}.{signature BASE64エンコード}は以下のようになります。
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoiNDZjNGYyODFmODExNDhjOWI4NDZjNTkyNjJhZTU4ODhAZXhhbXBsZS5jb20iLCJpYXQiOjE2MzQ3MTEzNTgsImV4cCI6MTYzNDcxNDk1OH0.RqOaErJWZc_ZGijL5r0a892NnQL_zbkgchThW3j4pzG_qMqtOgex2odEs8JFsPfQ2c8_2BkaUMckNIN3C27t2RsbppJYl3nQr9w2Jb6x9LJR1Ym3pJVlpRvarracRwa00OgVc0mZ5dkn3B4I55GpKjZ3oOLfW7Xw0OAj8fEYCmWJmma3xQQrScJAUqN-jTZ7T3C6-ieVo3IhTRopzS5cru3ilQWekQ6-fRTPr8W4EV9B0u8wXhCxT90mlAYtebPvyovpPTNhi8Oq8rO_gVnpSMNkDtZ6p6OpC7_XG7ZcjUo7KRCxyPLe2-TmeWtV0jL5vqsjnlAznKtw5mPGOwpjVQ
以降のTokenリクエストでは、生成したJWTをassertionパラメータとして渡します。
参考
- JWT生成については、ライブラリの利用を推奨します。
- 一例として、Javaの場合には以下のようなライブラリを利用できます。
https://github.com/jwtk/jjwt
https://github.com/auth0/java-jwt
https://bitbucket.org/b_c/jose4j/wiki/Home
https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home
Access Tokenの発行
Request URL
POST https://auth.worksmobile.com/oauth2/v2.0/token
Request Headers
Content-Type : application/x-www-form-urlencoded
Request Body
以下の項目をPOSTで送信する。
パラメータ | タイプ | 必須 | 説明 |
---|---|---|---|
assertion | String | Y | JWTの値 |
grant_type | String | Y | urn:ietf:params:oauth:grant-type:jwt-bearer (固定) |
client_id | String | Y | Client ID |
client_secret | String | Y | Client Secret |
scope | String | Y | 利用する scope 。複数の scope を設定する場合は半角スペース" "で区切る |
Request Example
curl --location --request POST 'https://auth.worksmobile.com/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoiNDZjNGYyODFmODExNDhjOWI4NDZjNTkyNjJhZTU4ODhAZXhhbXBsZS5jb20iLCJpYXQiOjE2MzQ3MTEzNTgsImV4cCI6MTYzNDcxNDk1OH0.RqOaErJWZc_ZGijL5r0a892NnQL_zbkgchThW3j4pzG_qMqtOgex2odEs8JFsPfQ2c8_2BkaUMckNIN3C27t2RsbppJYl3nQr9w2Jb6x9LJR1Ym3pJVlpRvarracRwa00OgVc0mZ5dkn3B4I55GpKjZ3oOLfW7Xw0OAj8fEYCmWJmma3xQQrScJAUqN-jTZ7T3C6-ieVo3IhTRopzS5cru3ilQWekQ6-fRTPr8W4EV9B0u8wXhCxT90mlAYtebPvyovpPTNhi8Oq8rO_gVnpSMNkDtZ6p6OpC7_XG7ZcjUo7KRCxyPLe2-TmeWtV0jL5vqsjnlAznKtw5mPGOwpjVQ' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode 'client_id=ZbsOq6zjt0IhtZZnrc' \
--data-urlencode 'client_secret=oRm3M_nBg6' \
--data-urlencode 'scope=bot,user.read'
Response Body (JSON)
パラメータ | タイプ | 説明 |
---|---|---|
access_token | String | Access Token |
refresh_token | String | Refresh Token |
token_type | String | Bearer |
expires_in | String | Tokenの有効期限 (有効期限: 24時間) |
scope | String | Access Tokenで利用できるscope |
Response Example
{
"access_token":"jp1AAABFNKyxc7xsVRQVKrTNFchiiMkQrfJMDM6whobYxfbO4fsF23mvuxRvSuMY57DG4uPI/NI4eNMSt8sroqpqFhe3HemLI3OvCar5FFfOQdqUBgqFA/MaHZVXHqsNJgoX7KaGwDTum+zhEyfwjGSrrJZfSoRpTHHrwny4F4UDEA1Lep3dVUUUKAIQHcq0TwCjiWkMnJAXMEFFfbdVzH3FCv+kpb2OH1NbYzL376fXLh3vMUlyRBXPTf3Lv0bK5NsvjR3BNMR3GSvVzjM59lR5ctBK8PvtTdmaHbVGXzJBHv+S3mp1UuD0szSuxCsWUrdCS7/PiWbQwM4++k+WM/bta5EB9v9s9YQGlyklE3fqhnYLGx/9jWanFgrvptCambOW8lv5A==",
"refresh_token":"jp1AAAAVq8kTeVPKkD11iLMP1mTqzYOd2T/r2x6QoBM2P3D8X6FfDi9wG5Hepsmh/LVpo3n3d/jcP/rnhtEw1VOpU4MJnxHVzu1x5VhKRmG/o63HERu2bnMtFHQVsjhljcf5fpm+Q==",
"scope": "bot",
"token_type": "Bearer",
"expires_in": 86400
}
Service Accountを利用したJWT認証に失敗するとエラーを返します。レスポンスボディを参照ください。
注意
- Access Tokenの発行時間をTokenと共に保存し、APIの利用時にはTokenの有効期限を確認することを推奨します。
- Access Tokenの有効期限内であっても、再発行を行うと以前のTokenは無効になります。
Access Tokenの再発行
User Account認証(OAuth)を参照してください。
Token Revoke
User Account認証(OAuth)を参照してください。
Access Tokenの使用
発行されたAccess Tokenは、ソースコード内にて以下のように使用します。
注意
- Authorizationタイプに'Bearer'を明示してください。'Bearer'と'Token'の間には半角のスペースを必ず入れてください。
PostMethod method = new PostMethod(url);
method.setRequestHeader("Authorization", "Bearer AAAA5IdUiCj5emZowcf49VRu7qbb548g6aGE");
Service Accountで利用できないAPI
以下のAPIは重要なユーザー情報を取り扱うため、Service Account認証で発行されたAccess Tokenでは呼び出すことができません。
Scopes | APIs |
---|---|
mail mail.read |
/users/{userId}/mail* |
file file.read |
/users/{userId}/drive /sharedrives |
file file.read group.folder group.folder.read |
/groups/{groupId}/folder* |