Closed kyosu-1 closed 1 month ago
middlewareでtokenからuserIDを取っているが、client credential flowだとuuid.Nilとなる。 https://github.com/traPtitech/traQ/blob/39e29ddb896e1bee7dc9b09147ed80fd985678fc/router/oauth2/token_endpoint.go#L285
https://github.com/traPtitech/traQ/blob/39e29ddb896e1bee7dc9b09147ed80fd985678fc/router/middlewares/user_authenticate.go#L65 ここでuidがuuid.Nilだと500エラーが返されてしまう
client credentials flowを利用するにはここら辺の改修も必要
影響範囲が大きいのでclient credentials flowの完全対応はconfidential clientのサポートと切り分けてissueを立てた方が良さそう
概要
OAuth2.0ではclientが機密情報を安全に扱えるかどうかで
public
とconfidential
の2種類のclient_typeが定義されている。(https://datatracker.ietf.org/doc/html/rfc6749#section-2.1)public clientとconfidential clientの区別はテーブル定義では含まれているが、defaultがfalse(public client扱い)になっている。このため、DB上で直接値を書き換えない限りはconfidential clientの作成が行えない
confidential clientの場合でのみ利用可能なclient credentials flow はサポートされているが(/tokenエンドポイントでgrant_type=client_credentialsとする)、これが事実上利用できなくなっている。(client credentials flowは特定のユーザーに紐づかないm2mのリソースアクセスで利用できる。)
また、tokenエンドポイントを叩くのがサーバーサイドであればconfidential clientとなるので、認可コードフローを使っている場合でもユースケースとしてconfidential_clientになっているものが多いはず。現状は恐らくconfidential_clientとpublic_clientの概念が意識されずに、運用されていそう。例えばpublic_clientの場合はclient認証は必須ではない。この仕様は実装レベルだと反映されている(public client ではclient認証を行っていない)が、利用者側からしたらclinet_secretが必ず発行されているので、client認証が必須と思われる可能性がある。public clientの場合はclient_secretを発行しない形としたいが、破壊的になるかも
方針
後方互換性を保つのであれば以下のような形で実装を行うのが良さそう
public
とconfidential
)されたclient_type
or booleanのconfidential
をリクエストボディに含める。いずれの場合でも後方互換性の観点からdefault値をpublic_clinetとしてnot requiredとする必要がある。UIの対応
BE側の対応が完了したらUI側の対応も必要。client typeを設定可能なように