traPtitech / traQ

traQ - traP Internal Messenger Application Backend
MIT License
421 stars 28 forks source link

OAuth clientのconfidential clientのサポート #2402

Closed kyosu-1 closed 1 month ago

kyosu-1 commented 4 months ago

概要

OAuth2.0ではclientが機密情報を安全に扱えるかどうかでpublicconfidentialの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を発行しない形としたいが、破壊的になるかも

方針

後方互換性を保つのであれば以下のような形で実装を行うのが良さそう

UIの対応

BE側の対応が完了したらUI側の対応も必要。client typeを設定可能なように

kyosu-1 commented 4 months ago

https://github.com/traPtitech/traQ/blob/4f6c04807c8ac6500ab1ad60fbec4c122d07ab14/router/middlewares/user_authenticate.go#L50

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を利用するにはここら辺の改修も必要

kyosu-1 commented 4 months ago

影響範囲が大きいのでclient credentials flowの完全対応はconfidential clientのサポートと切り分けてissueを立てた方が良さそう