search
LoginSignup
35
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

【OAuth 2.0】ぼくのかんがえたさいきょうのscope

※ OAuth 2.0の規程に則って「認可サーバーを作成する」側の話です。

OAuth 2.0では、 scope というパラメーターでアクセス範囲を表します。

クライアントは scope リクエストパラメーターを用いて要求するアクセス範囲を明示することができる.
同様に, 認可サーバーは発行されたアクセストークンの範囲をクライアントに通知するために scope レスポンスパラメーターを使用する.

このscopeですが、どんな形式にするかは実装者に委ねられています。RFCが定めている制約といえば下記くらいのものです。

  • 大文字と小文字は区別する
  • スペースは使えない(複数のscopeをスペース区切りで表すため)
  • scopeを省略しても良いことにしても良い(その場合デフォルト値を定義する)

ref. https://openid-foundation-japan.github.io/rfc6749.ja.html#scope

めっちゃ自由。自由すぎてどんな形式にするのが良いかちょっと悩みます。
この記事では他社事例を見た後、ぼくのかんがえたさいきょうのscopeを提示します。

他社事例を見てみる

悩んだときは先人の様子を伺います。

GitHub OAuth Apps

Scope一覧

  • (no scope)
  • repo
  • repo:status
  • repo_deployment
  • public_repo
  • repo:invite
  • security_events
  • admin:repo_hook
  • write:repo_hook
  • read:repo_hook
  • admin:org
  • write:org
  • read:org
  • admin:public_key
  • write:public_key
  • read:public_key
  • admin:org_hook
  • gist
  • notifications
  • user
  • read:user
  • user:email
  • user:follow
  • delete_repo
  • write:discussion
  • read:discussion
  • write:packages
  • read:packages
  • delete:packages
  • admin:gpg_key
  • write:gpg_key
  • read:gpg_key
  • workflow

ref. https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes

特徴

  • コロン(:)区切りになっている。
  • write:discussionread:discussionのように、「権限:リソース」の形をしているものが散見される。その視点で見ると、「権限」にあたるものはread, write, admin, deleteの4つ。
  • scopeなし(空欄)でパブリックな情報へのread only権限が与えられる。

「権限:リソース」のフォーマット良さそう。

YouTube Data API

Scope一覧

ref. https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps?hl=ja#Obtaining_Access_Tokens

特徴

  • URLの形をしている。
  • URLを叩くと、text/plainでscope名が返ってくる。
  • scopeなし(空欄)はサポートされていない。

URLを内部でどのように使っているのか気になる。httpでアクセスしたりするのかな。

LINE Social API

Scope一覧

  • profile
  • profile%20openid
  • profile%20openid%20email
  • openid
  • openid%20email

ref. https://developers.line.biz/ja/docs/line-login/integrate-line-login/#scopes

特徴

  • あらかじめ空白文字(%20)で区切られた状態で列挙されている。例えばemailは単体でscopeにならないので、RFCに準拠してないと言えそう。
  • scopeなし(空欄)はサポートされていない。

Twitter

scopeはなし。
OAuth 1.0aでの認可がまだ主流のようで、OAuth 2.0ではClient Credentials Grantでのpublicな情報へのアクセスしかサポートしていないため、scopeでアクセス範囲を決める必要がないのだろう。

ref. https://developer.twitter.com/en/docs/authentication/api-reference/token

ぼくのかんがえたさいきょうのscope

先人たちのscopeを見てみましたが、(Twitterを除いて)三者三様でした。

リソースサーバーがどんなAPIを提供するのかに依ってscopeのフォーマットも変わると思いますが、ここではRESTfulなAPIへの認可を考えることにします。

さて、本題のぼくのかんがえたさいきょうのscopeは、これだっ!!!

  • read:リソース名
  • write:リソース名

理由

このscopeの前提となる思想は下記2つです。

  • 最小権限の原則に則って必要最低限の権限のみを認可できるように、scopeのアクセス範囲はなるべく小さくしたい。
  • scope名を見ただけでアクセス範囲が分かるような明快なものが良い。

この思想をもとに、下記のように考えました。

  • RESTの「リソース」という概念を利用して、リソース単位で切ると、明快で小さく権限を分けられるだろう。
  • リソースに対してなんでもできてしまう権限は大きいので、リソースに対する動作でさらに権限を分ける必要がある。下記の理由で1つのリソースに対しreadとwriteの2つの権限に分けることにした。
    • HTTP動詞で言うなら、GETをread、POST, UPDATE, DELETEをwriteとすれば良いので、明快だろう。
    • HTTP動詞(GET, POST, PUT, DELETE)や、Railsのcontrollerのアクション名など、より細かい権限分離も考えたが、リソースの新規作成ができるclientには、作成したリソースの更新・削除する権限も与えたいという考えで、readとwriteという分け方にした。
    • readとwriteはLINUXのファイルパーミッションでも登場するので、馴染み深く明快だろう(executeは使わないけど)。

オマケ 〜Railsの場合〜

「リソース名」は単数形にしても複数形にしても良いですが、Railsではcontroller_nameでコントローラー名(基本的にリソースの複数形)が取れ、私はこれを利用するために複数形にしました。

# こんなアクセスのとき... http://hoge.jp/articles
controller_name
# => “articles”
# こんなのが取れる!

これを利用すれば、scopeの検証は2つのメソッドのみで事足ります。controller concernなどに書くと良いと思います。

def required_read_scope
  scope_name = "read:#{controller_name}"
  render_unauthorized unless current_access_token.scopes.include?(scope_name)
end

def required_write_scope
  scope_name = "write:#{controller_name}"
  render_unauthorized unless current_access_token.scopes.include?(scope_name)
end

あとはこのメソッドを各controllerのbefore_actionで、指定したアクションの前に呼び出すだけです。

class ArticlesController < ApplicationController
  before_action :required_read_scope, only: %i[index show]
  before_action :required_write_scope, only: %i[create update destroy]

  ...
end

OAuth 2.0の他の仕様で迷ったら

私がOAuth 2.0の自由な仕様で迷ったときに、各社の仕様をこちらにまとめました。他の仕様で迷っているときは参考になるかもしれません。
https://qiita.com/murs313/items/078025d671e937a09285

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
35
Help us understand the problem. What are the problem?