Entra ID（旧 Azure AD とか B2C）でリフレッシュトークンを取り消したい

# Entra ID系でリフレッシュトークンを取り消し（Revoke） たい

タイトル通りというニッチな要求に対する覚え書きです。Entra 全般の話かとは思いますが、ここでは Azure AD B2C に対して行っています。

## お手軽にポータル

ポータルのユーザー画面から任意のユーザーを選択すると、上部に「セッションの取り消し」というボタンが表示されます。これをクリックすると、該当ユーザーのトークンが取り消しされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34017/522e7bfe-3591-beee-b691-5825ea043850.png)

## Grpah API を叩く

Revoke には Beta 含めていくつか APIがあるようです。ググラビリティが低くて探しにくかったので回り道含めて記録しておきます。

1つ目に見つかったのが以下。

[user: invalidateAllRefreshTokens - Microsoft Graph beta | Microsoft Learn](https://learn.microsoft.com/ja-jp/graph/api/user-invalidateallrefreshtokens?view=graph-rest-beta&tabs=http)

ただし、記事通り beta APIですし、

> この API は、一般提供状態には昇格されません。 代わりに、 ユーザー revokeSignInSessions API を使用することをお勧めします

との事なので、この API はオススメしません。途中までこの記述を見逃していたので、しばらくこれを使って検証していました。

というわけで、こちらの API を使いましょう。`v1.0` としてリリースされています。

[user: revokeSignInSessions - Microsoft Graph v1.0 | Microsoft Learn](https://learn.microsoft.com/ja-jp/graph/api/user-revokesigninsessions?view=graph-rest-1.0&tabs=http))

### 権限

ツールで使いたかったので、アプリ登録しました。専用のアプリなどを作って、 `User.RevokeSessions.All` をパーミッションとしてあたえましょう。クライアントシークレットも作成しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34017/1056b2b3-c97b-c3fb-380a-8cadd06d8c22.png)

## APIを叩く

さっと試したかったので、bash + curl で書いてしまいました。アクセストークン取得して、該当APIを叩きます。

```sh
upn="..."
token=$(\
curl --silent --request POST \
  --url https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=client_credentials \
  --data client_id=${CLIENT_ID} \
  --data client_secret=${CLIENT_SECRET} \
  --data scope=https://graph.microsoft.com/.default | jq -r ".access_token"\
)

curl --request POST \
  --url https://graph.microsoft.com/v1.0/users/${upn}/revokeSignInSessions \
  --header "Authorization: Bearer ${token}" \
  --header "content-length: 0"
```

以下のようなレスポンスが返ってくればOKみたいです。

```
{"@odata.context":"https://graph.microsoft.com/beta/$metadata#Edm.Boolean","value":true}%
```

割愛しますが、リフレッシュトークンから新しいアクセストークンを取得しようとすると、以下のエラーが返ってきて、Revokeされていることが確認できます。

```json
{
  "error": "invalid_grant",
  "error_description": "AADB2C90129: The provided grant has been revoked. Please reauthenticate and try again.\r\nCorrelation ID: 1ae32029-b7be-40fa-88fe-cca5c5a177dd\r\nTimestamp: 2024-12-11 08:17:51Z\r\n"
}
```

## graph cli を使う

存在は知っていたのですが、あまり使ったことがなかったのでこちらでも試してみました。.NET ベースの graph cli ツールです。

[microsoftgraph/msgraph-cli: CLI tool for Microsoft Graph based on .NET](https://github.com/microsoftgraph/msgraph-cli)


ログイン方法はいくつかあります。 device コードでユーザーとしてログインしてもいいのですが、先ほどの続きなので、サービスプリンシパル使います。

適当に環境変数を設定の上、 `mgc login`します。

```sh
export AZURE_TENANT_ID="..."
export AZURE_CLIENT_ID="..."
export AZURE_CLIENT_SECRET="..."

mgc login --strategy Environment
```

該当サービスプリンシパルでログインできます。Revokeするには、`mgc users revoke-sign-in-sessions` を使います。User id もしくは、 user principal name でOKです。

```sh
mgc users revoke-sign-in-sessions post --user-id [upn or user_id]

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Edm.Boolean",
  "value": true
}
```

上記のようなレスポンスがあればOKです。

## まとめ

サインイン周りのテストするときに、最短でも1日のリフレッシュトークンの扱いをテストするのにちょうど良い感じになりました。

以上