Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client credentials grantを利用できるように #2433

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

kyosu-1
Copy link
Member

@kyosu-1 kyosu-1 commented May 22, 2024

対応issue: #2403
client credentials grantを利用できるように

issueに記載の通りこのflowではトークン(テーブル)のuserIDがNilなので、middlewareでuser情報は取れず、contextに入れることができないことに注意。client credentials grantのフローで取得したトークンを利用したAPIアクセスの中でcontextからUserを参照使用してたらpanicが起こる。

許可するpermissionは、handler中でuser情報をcontextから取得するようなものは扱えないことを前提として選択
(ユースケース的にはユーザー情報、ユーザーのグループ情報の取得が挙がっていて、そちらは対応可能だと思われる。)

@kyosu-1 kyosu-1 linked an issue May 22, 2024 that may be closed by this pull request
Comment on lines +10 to +15
var clientPerms = []permission.Permission{
permission.GetUser,
permission.GetUserTag,
permission.GetUserGroup,
permission.GetStamp,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

knoQで使いたいのでGetUsersやGetUserGroupsがあると助かります:pray:
Draftで仮置きしてるだけかもですが

Copy link
Member Author

@kyosu-1 kyosu-1 Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetUsersとGetUserGroupsのAPIはそれぞれpermission.GetUserとpermission.GetUserGroupを持っていれば叩けますね。(APIと一対一対応ではなく、一つのpermissionが複数のAPIを対象として許可しています。)
ref:

apiUsers.GET("", h.GetUsers, requires(permission.GetUser))

apiGroups.GET("", h.GetUserGroups, requires(permission.GetUserGroup))

一応permissionのListは

var List = []Permission{
ここの一覧として載っています。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

少なくない?そんなことない?
自身のユーザーに関連しないものは許可してよさそう
https://github.com/traPtitech/traQ/blob/master/service/rbac/role/read.go

Copy link
Member Author

@kyosu-1 kyosu-1 Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見落としあるかもしれませんが、確認した限りはこれら以外のpermissionで許可されるエンドポイントの中には getRequestUserID が 含まれてそうな感じでした。
e.g. permission.GetMessage で許可されるエンドポイントの中にGetDirectMessages が含まれる

func (h *Handlers) GetDirectMessages(c echo.Context) error {

apiUsersUID.GET("/messages", h.GetDirectMessages, requires(permission.GetMessage))

permissionで許可するエンドポイントの対応関係を上手く考え直せば与えられる許可は増やせそうですが、影響範囲大きくなるのでひとまずこれぐらいでも良いかなと思ってます。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

うーん、なるほど あまりきめ細やかに制御されてなくて難しいんですね
そうしたらその権限の制御のやり方を考え直す(より細やかにする)か、client credentials grantにそもそもユーザーをどうにかして紐づけるか、とかを考えたいところですね

少なくとも今やらない(できなかった)のなら、その理由をコメントとかで書いておくべきだと思います

Copy link
Member Author

@kyosu-1 kyosu-1 Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue立てつつコメント残す形にしました

service/rbac/role/client.go Outdated Show resolved Hide resolved
Co-authored-by: Hibiki Seki <[email protected]>
@kyosu-1 kyosu-1 marked this pull request as ready for review June 21, 2024 10:39
@kyosu-1
Copy link
Member Author

kyosu-1 commented Jun 21, 2024

client credentials grantによって必ずしもhandlerの中でcontextにUserInfoが入ってるとは限らなくなり、入っていない状態でアクセスしようとしたらpanicが起きてしまう。

c.Get(consts.KeyUser).(model.UserInfo)

を関数化してアサーションに失敗したらエラーを返した上で利用側でハンドリングした方がよいかもしれない

イメージ

func GetUser(ctx echo.Context)  {
  user, ok := c.Get(consts.KeyUser).(model.UserInfo)
  if !ok {
    return model.UserInfo{}, UserKeyError
  }
  return user, nil
}

ただし影響範囲が大きくて大変そう。また、現状は上記のようなユーザー情報の取得が発生しないAPIのみにアクセス可能なようにclient credentials grantで付与するpermissionを絞っているので、上記の対応はしなくてもよいかも

@@ -48,6 +48,11 @@ func GetSystemRoles() Roles {
oauth2Scope: true,
permissions: permission.PermissionsFromArray(profilePerms),
},
Client: &systemRole{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新しくrbacのロールとpermission一覧を更新するときはmigrationが必須です

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo:
https://github.com/traPtitech/traQ/blob/4ac16404c3a12e44ef1503b0d8cd9b2899deeede/migration/v35.go

v35(), // OIDC実装のため、openid, profileロール、get_oidc_userinfo権限を追加

ここら辺と同じように

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OAuthでclient credentials flowが利用可能なように
4 participants