Service Account認証 (JWT)

    Service Account認証とは、アプリ専用の仮想管理者アカウントを使用して認証を行い、Access Tokenを発行してAPIを利用する方法です。
    Service Account認証では、Json Web Token (以降、JWT)を使用してAccess Tokenを発行します。
    Developers Consoleに登録したアプリのService Account認証 (JWT)を使用したAccess Tokenを発行するフローは以下の通りです。

    1. アプリ開発者は、Developer ConsoleよりService Accountを発行する
    2. アプリは、Service Accountを使用してJWT生成する(RFC-7519)
    3. アプリは、JWTを電子署名する (signature) (RFC-7515)
    4. アプリは、LINE WORKSにAccess Tokenの発行を要求する (RFC-7523)
    5. アプリは、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がある

    事前準備

    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)を参照してください。

    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*