🌐

IETF OAuth WGの仕様全部...じゃなく差分見る - 2021/12

2021/12/03に公開

こんばんは、ritouです。

Digital Identity技術勉強会 #iddanceのカレンダー | Advent Calendar 2021 - Qiita 3日目の記事です。

いわゆるOAuthの仕様についての差分チェックです。去年もアドカレで書きましたが、継続することが大事ですね。

IETF OAuth WGの仕様全部...じゃなく差分見る - 2020/12

仕様のありか

ここです。

Oauth Status Pages

ちなみに記事は年に一回しか書いてませんが、IETFのMLを追うのも辛いのでたまにここから仕様自体を見てます。

RFCになった系 : 22 -> 25 (←仕様の数)

ここ1年でRFCになったのは3つあります。

JWTなATについてはセッショントークンの話で若干話題になった件とかもあって、今後もあーでもないこーでもないと語られそうな感じですが、特徴を理解して使いたければこれに従って作ればいいんじゃないかと思います。

残りのJAR, PAR についてはこの前どこかの勉強会でお話ししましたので参考にしてみてください。

これらの Authorization Request をセキュアにする仕組みが使われるのはFAPI相当のセキュアなユースケースになるのでしょうけれど、データの受け渡し方をどのようにセキュアにできるかという観点では覚えておいて損にはならないテクニックだと思います。

まだRFCになってない系

前回の記事ではスクリーンショットを貼るのを忘れたのでどいつがどうなったかがわかりません。
新しいのはそんなに出てきてなさそうですが、反省を踏まえて今回は貼っておきましょう。

なんか少なくね?

RFC-Editor's Queue:

もうRFC直近ってやつです。

JWT Response for OAuth Token Introspection

RFC7662で定義されているトークンイントロスペクションAPIのレスポンスをJWT形式にするという仕様です。
ユースケースがなかなか思い浮かばないかもしれませんが、トークンイントロスペクションAPIでPIIを返すユースケースではASがその値を返したことを検証できると嬉しい場合がある、みたいなことが書かれています。
OIDCのIDTokenでは別の発行者の署名付きでユーザー情報を伝達する、いわゆるAggregated Claimsのような考え方が仕様策定当初からありましたが、AS/RSが分離していて、RSがアクセストークンに紐づけられたユーザーの情報を利用したりClientに渡したりする ユースケースとかで使われるのかもしれません。この前紹介したGNAPにも関連しそうですが、AS/RSの関係性については今後も注目する必要があるでしょう。

ざっと処理の流れを説明すると、Resource Serverは Accept: application/token-introspection+jwt というヘッダを指定することでJWT形式のレスポンスを要求します。

POST /introspect HTTP/1.1
Host: as.example.com
Accept: application/token-introspection+jwt
Content-Type: application/x-www-form-urlencoded

token=2YotnFZFEjr1zCsicMWpAA&...

JWT形式のレスポンスのHeader/Payloadは次のようになります。

# header
{
  "typ": "token-introspection+jwt",
  "alg": "RS256",
  "kid": "wG6D"
}

# payload
{
  "iss":"https://as.example.com/",
  "aud":"https://rs.example.com/resource",
  "iat":1514797892,
  "token_introspection":
     {
        "active":true,
        "iss":"https://as.example.com/",
        "aud":"https://rs.example.com/resource",
        "iat":1514797822,
        "exp":1514797942,
        "client_id":"paiB2goo0a",
        "scope":"read write dolphin",
        "sub":"Z5O3upPC88QrAjx00dis",
        "birthdate":"1982-02-01",
        "given_name":"John",
        "family_name":"Doe",
        "jti":"t1FoCCaZd4Xv4ORJUWVUeTZfsKhW30CQCrWDDjwXy6w"
     }
}

token_introspection のところがRFC7662の内容です。
また、aud を適切に指定できるように、ASがRSをちゃんと管理する必要がありますね。
あとはサポートする場合のメタデータなどが定義されています。

IESG Processing:

これもだいぶ仕様が煮詰まってきてる段階です。

OAuth 2.0 Authorization Server Issuer Identification

(記事書いてる途中で03から04に変わった。)
これはいわゆる "mix-up attacks" への対策です。

この攻撃はあまり聞いたことない方もいらっしゃるかと思いますが、

  1. Client, 悪意のあるAS, 悪意のないASが存在する
  2. Clientは悪意のあるASに認可リクエストを送り、悪意のあるASは悪意のないASへの認可リクエストを流す
  3. 悪意のないASは諸々終わったら Client に認可レスポンスを戻す
  4. Clientは悪意のあるASにアクセストークンリクエストを送り...あとは悪意のあるASが色々できる

みたいな話です。悪いのはIdPでもProxyでもいいですね。
で、この対策として、認可レスポンスに iss パラメータとして悪意のないASのissuerの値を含み、Clientは認可レスポンスを受け取った時点で「え?なんでこっちから来てんの?」って検知できるわけです。

# Success
HTTP/1.1 302 Found
Location: https://client.example/cb?
  code=x1848ZT64p4IirMPT0R-X3141MFPTuBX-VFL_cvaplMH58
  &state=ZWVlNDBlYzA1NjdkMDNhYjg3ZjUxZjAyNGQzMTM2NzI
  &iss=https%3A%2F%2Fhonest.as.example
  
# Error
HTTP/1.1 302 Found
Location: https://client.example/cb?
  error=access_denied
  &state=ZWVlNDBlYzA1NjdkMDNhYjg3ZjUxZjAyNGQzMTM2NzI
  &iss=https%3A%2F%2Fhonest.as.example
  • 複数IdPとOAuthする
  • redirect_uri が共通
  • 信頼できないIdPとつなぐ可能性がある

みたいな前提条件なのでClientは気をつければ良さそうですが、Server側はちゃんと実装されてるかわからないのでこの仕様をサポートして iss の値を返してみても良いかもしれません。

というお話でした。

Active:

現在策定中なのがこちらの3つですね。

詳細はまぁいいでしょう。

Recently Expired:

以下の2つがExpired になっています。

セキュリティBCPだけど...まぁいいか。

ということで、今年もOAuth WGのRFC周りを振り返ってみました。
また来年やりましょう。

Digital Identity技術勉強会 #iddanceのカレンダー | Advent Calendar 2021 - Qiita 明日も私かもしれません。

ではまた!

Discussion