OAuth 2.0
OAuth認可の流れ
4つの登場人物
Resource Owner
Protected Resource
Client (OAuth)
認可サーバー
用語
認可コード
Access Token
OAuthのScope
Refresh Token
書籍
『OAuth徹底入門』
『OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本』
『雰囲気でOAuth2.0を使っているエンジニアがOAuth2.0を整理して、手を動かしながら学べる本』
実践 Keycloak OpenID Connect、OAuth 2.0を利用したモダンアプリケーションのセキュリティー保護
2022/10/15
#WIP
https://www.buildinsider.net/enterprise/openid/oauth20
1.0がモノリスな感じだったのに比較して、2.0はモジュラーな感じになった
2012年頃?
RFC6749
RFC6750
認可プロトコル
委譲プロトコル?
と言われても全くわからんが
リソースを管理している誰か(リソース所有者)がソフトウェア·アプリケーションに所有者自身のなりすましをさせるのではなく、リソース所有者の代わりとして対象のリソースへのアクセスを許可するための手段
何を言っているのかわからん
まず登場人物がわからない #??
2つのサービスがあるとする
S3のようなストレージサービス
印刷サービスP
これら2つは別の企業が管理しているサービス
これら2つを利用しているuser X
Pは、APIを介してS3にアクセスすることができる
Xから見れば、この2つが連携しているので便利
しかし、これを実現するためには、Pに「XのS3のパスワード」を教えてないといけない
めっちゃ安易に考えれば、「パスワードを共有する」になる
両方とも同じ企業が作っていたり、1つの企業内の話であれば、責任を持ってパスワード管理をさせればいい
これはセキュリティ的に良くない
ここでOAuthをつかう
Pに、S3へのアクセス権を委譲し、パスワードを教えなくても連携させることができる
どうやって #??
OAuth以外での同じ問題の実現方法
パスワードを共有する
Client (OAuth)に、リソースへアクセスするパスワードを教えちゃう
clientとresourceを同じ企業内で使っているとかならさほど問題は起きない
責任を持ってpassを保存すればいい
元々resouceのpassを持っているようなものだし
第三者のclientには応用できない
こうした場合、resourceにアクセスしてきたものが、実際のuserなのか、clientなのか区別がつかないという問題もある
随時?userへの問い合わせをする
clientが、resourceにアクセスする必要が出てきた時に、userにpassを聞く
clientはそれを使って、resourceにアクセスする
ただ、毎回聞くのもだるいので、clientはそのpassを保存する
結局clientにpassを教えているmrsekut.icon
clientがそれを漏洩させたら終わる
LDAP認証がこんな感じなのらしい
こうした場合、resourceにアクセスしてきたものが、実際のuserなのか、clientなのか区別がつかないという問題もある
権限が全て渡されるので、clienは削除も追記もなんでもし放題になる
resource側がそれを判別して制限することができない
resourceのサービスが、clientに開発者キーを渡す
e.g. Twitterが、黒歴史クリーナーに開発者のキーを渡す
Xのpassをclientに教えなくて済む
userがXであるとかYであるとか関係なく何でもし放題
Xとしてツイートすることも、Yとして削除することもできる
2つのサービスが同じ企業が管理しているならありうる
resouceが2種類のpassを発行する
clientに教える用のpassを発行する
OAuthとだいたい同じことができる
uesrは2種類のpassを覚えておく必要がある
Twitter連携のやつもこれか
https://gyazo.com/eaa2804a434b4b34161915d7829bf594
黒歴史クリーナーの管理者に、自分のTwitterのパスワードを教えずに、自分のツイートの操作をさせることができる
これは、Twitterが、黒歴史クリーナーにツイート削除の権限を委譲しているから
バック・チャネル・コミュニケーション
/mrsekut-book-4798159298/124
userが干渉しない
clientとauth serverらが直接やり取りする
Front-channel communication
OAuth
クライアントが、ユーザに対して「権限を委譲することのリクエスト」をできるようにする仕組み
トークンの取得方法と、トークンの使用方法に関する仕様
システムをまたいで認可を行える
委譲プロトコル
良い点
ユーザーは、アクセストークンに触れない
覚える必要も管理する必要もない
クライアントには過不足ない権限を与えられる
クライアントがトークンを漏洩した時は #??
言うて、許した権限程度のものだからそこまで問題にならない?
パスワードなどが直接流出するわけではない
ユーザーとクライアントが区別される
一度トークンを取得できれば、ユーザーがいなくても、やり取りし続けられる
Basic認証やCookieとは異なる点
/mrsekut-book-4798159298/068
TOFU
credential
認証に用いられる情報
e.g. ID、password
OAuthは、HTTPS上でしか使えない
#??
認可サーバーは誰が管理してるの?
認可サーバーはなぜ複数種類存在するの?
それとも世界に1種類しかないの?
認可サーバーは何をやっているの
全てのクライアントとユーザのクレデンシャルとトークンを管理している?
ここが攻撃されたら結構やばい?
https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be
https://speakerdeck.com/noriyukitakei/wakarimioauth
https://www.youtube.com/watch?v=PKPj_MmLq5E
HS256を使った処理の流れ
たぶん一例mrsekut.icon
OAuthの話
この例がどこまで一般的な状況なのかわからん #??
/mrsekut-book-4798159298/507
前提
認可サーバーと、Protected Resourcesは秘密鍵を共有している
認可サーバーが、トークンの署名を行う
algの暗号化アルゴリズムを使って署名する
code:例.js
const accessToke = jose.jws.JWS.sign(
header.alg,
JSON.stringify(header),
JSON.stringify(payload),
new Buffer(sharedTokenSecret).toString('hex')
)
これによって、xxx.xxx.xxxの形式のtokenができる
Protected Resourceが検証する
code:例.js
const verified = jose.jws.JWS.verify(
token,
new Buffer(sharedTokenSecret).toString('hex'),
header.alg
);
if (verified) {
// 検証が成功しているので、JWTの中身を取り出したりできる
}
RS256を用いた例
/mrsekut-book-4798159298/513
前提
認可サーバーは、公開鍵と秘密鍵を持っている
Protected Resourcesは、公開鍵を持っている
認可サーバーで署名
code:Js
const accessToken = jose.jws.JWS.sign(
header.alg,
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
Protected Resourceが検証する
code:例.js
const verified = jose.jws.JWS.verify(
token,
publicKey,
header.alg
);
if (verified) {
// 検証が成功しているので、JWTの中身を取り出したりできる
}