Mais conteúdo relacionado
Semelhante a OpenID Connect入門 (20)
OpenID Connect入門
- 2. 筆者の自己紹介
• 土岐 孝平
• 合同会社 現場指向
– システム開発の支援
• Java、Spring Framework
– メモラキー
• 軽快でシンプルなメモアプリ
– https://www.memorarchy.com
• 書籍の執筆
– Spring入門
2
[改訂新版]Spring入門
- 6. OpenID Connectとは?
• 認証・認可のための標準化されたHTTPベー
スのプロトコル
• OpenID Foundationという組織が2014年に公
開
• 認可のプロトコルであるOAuth2.0を拡張して
いる
6
【補足】
「OpenID」と「OpenID Connect」は、指してるものが異なる。「OpenID」は2005年から
存在するプロトコルで、OAuth2.0の拡張ではない。「OpenID Connect」は2014年に
公開され、OAuth2.0を拡張している。いずれもOpenID Foundationという組織が促
進している。
- 13. OpenID Connectによる拡張
• 認証時の情報や、ユーザ情報を取得するた
めの仕様を追加
– IDトークンという概念を追加
• IDトークンの中に認証時の情報を含めることができる
– ユーザ情報を取得するための仕組みを追加
• 名前やメールアドレスなどの基本的な情報は項目名
が定められている
13ユーザ
承諾
&
IDトークン
ユーザ情
報を取得
・以降、本資料では、OpenID Connectの
ことを、「OIDC」と記載する。
・また、OIDCの意味の中に、暗黙的に
Auth2.0を含む。
- 14. 登場人物の役割と用語
役割 OAuth2.0の用語 OIDCの用語 本資料での呼び方
システムを使うユーザ Resource Owner End User ユーザ
ユーザが操作する端
末
User Agent -
(定義してない)
User Agent
トークンを発行するシ
ステム
Authorization Server OpenID Provider Authorization Server
トークンを発行しても
らうシステム
Client Relying Party Client
トークンを使ってアク
セスされるシステム
Resource Server -
(定義してない)
Resource Server
14
【補足】
・Resource ServerとAuthoriation Serverは、一緒のシステムかもしれないし、
別のシステムかもしれない(どちらでもよい)
- 17. フローの種類
名前 特徴 主なClientの種類
認可コードフロー トークンを発行する前に、認可コードを
やりとりすることで安全性を向上する
Webアプリ(MPA※1・SPA)
インプリシットフロー 認可コードを使わずにトークンを発行
する。リフレッシュトークンを利用でき
ない※2。現在は推奨されていない※3。
Webアプリ(SPA)
ハイブリッドフロー 認可コードを取得するタイミングでID
トークン・もしくはアクセストークンを取
得することが可能
?(筆者が利用シーンをイメージ
できていないため)
クライアント
クレデンシャルフロー
ClientのID・パスワードを使ってトーク
ンを取得する。発行されるアクセストー
クンはユーザと紐づかない。
バッチアプリ、他システムと連携
するバックエンドのシステム
リソースオーナーパスワード
クレデンシャルフロー
ユーザのID・パスワードを使ってトーク
ンを取得する。ClientにユーザのID・パ
スワードを渡す必要がある。
Authorization Serverの組織の公
式アプリ(例えば、SNSサイトの公
式スマフォアプリなど)
17
※1 Multi Page Application。リクエスト毎にサーバ側でHTMLを生成する昔ながらのWebアプリ
※2 アクセストークンをリフレッシュ(有効期限を更新するなど)する際に使用するトークン
※3 参考: https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09
- 18. エンドポイントの種類
名前 役割 提供元 関連するフロー
認可エンドポイント フローを開始するために必要な
情報(ClientのIDなど)を
Authorization Serverが受け取る
・Authorization
Server
・認可コードフロー
・インプリシットフロー
・ハイブリッドフロー
リダイレクト
エンドポイント
Authorization Serverが発行した
認可コードもしくはトークンを
Clientが受け取る
・Client
(SPAの場合は
Webサーバ)
・認可コードフロー
・インプリシットフロー
・ハイブリッドフロー
トークン
エンドポイント
IDトークン・アクセストークン・リフ
レッシュトークンを発行する
・Authorization
Server
・認可コードフロー
・ハイブリッドフロー
・クライアントクレデンシャルフ
ロー
・リソースオーナーパスワード
クレデンシャルフロー
ユーザ情報
エンドポイント
ユーザ情報を提供する ・Authorization
Server
・クライアントクレデンシャルフ
ロー以外の全てのフロー
トークン検証
エンドポイント
アクセストークンの有効性を検証
する
・Authorization
Server
・全てのフロー
18
- 30. Authorization Serverの調達について
• Authorization Serverを自前で実装してもよい
が、既存の製品やサービスを利用するのが
無難と思われる
• 製品やサービスの例
– 自前のサーバにインストールする場合
• Keycloak(https://www.keycloak.org/)
• OpenAM(https://www.openam.jp/)
– クラウドのサービスを利用する場合
• Auth0(https://auth0.com/)
• okta(https://www.okta.com/)
30
- 34. JWT(JSON Web Token)とは?
• IETFによって標準化されたデータ形式
– OIDCに特化したものではない
• クレイムとよばれるさまざまな情報をJSON形式で表現
– 一般的なクレイムは項目名が定義されている
• 例)「iss」というクレイムは、 発行元(issuer)を表す
• Base64URLでエンコードするため、空白の制約があるような
状況(HTTPのヘッダやクエリー文字列など)で使うことができ
る
• JWSとJWEという2つの形式があり、OIDCのIDトークンはJWS
形式となる
• JWS(JSON Web Signature)の特徴
– 電子署名されるため、データに信頼性(発行元の証明、改ざん防止)
がある
– 「ヘッダ」「ペイロード」「電子署名」の3つで構成される
34
- 42. 認可リクエスト(1/2)
• Authorization Serverに対して、フローを開始するための情報
をClientから渡す
• リクエストのパスの値はAuthorization Serverが提供する
– OIDCの仕様上はパスの値は決まっていない
• HTTPメソッドはGETもしくはPOST
• 主なパラメータ
42
パラメータ名 説明 値
scope アクセスの種類を指定
空白区切りで複数指定可能。仕様で
定義されてるもの(後述)と、任意に定
義したものを指定できる。「openid」
は必須
response_type レスポンスの種類(後述) 「code」
client_id
Clientを一意に識別するためのID。
Authorization Serverに事前に登録して
おく。
登録したClient ID
redirect_uri
ClientのリダイレクトエンドポイントのURL。
Authorization Serverに事前に登録して
おく。
リダイレクトエンドポイントのURL
- 50. トークンリクエストのサンプル
50
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&client_id=s6BhdRkqt3
&redirect_uri=https://client.example.org/app.html
- 51. トークンレスポンス
• IDトークン・アクセストークン・リフレッシュトー
クンをJSON形式で返す
• 主な属性
51
属性名 説明 値
id_token IDトークン 生成されたIDトークンの値
access_token アクセストークン 生成されたアクセストークンの値
token_type リソースサーバにアクセストークンを
送信するときの手段
「Bearer」※
refresh_token リフレッシュトークン 生成されたリフレッシュトークンの値
expires_in
アクセストークンの有効期間(本レス
ポンスが作られてからの経過秒数)
有効期間の秒数
※HTTPのリクエストヘッダに「Authorization: Bearer {トークンの値}」を指定する。
- 52. トークンレスポンスのサンプル
52
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
}
- 53. ユーザ情報リクエスト
• ユーザ情報を取得する
• アクセストークンをリクエストに含める
– ヘッダで「Authorization: Bearer {トークンの値}」を
指定する
• リクエストのパスの値はAuthorization Server
が提供する
• HTTPメソッドはGETもしくはPOST
• サンプル
53
GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG
アクセストークン
- 55. Resource ServerのAPIの呼出
• アクセストークンを使って、Resource Serverの
任意のAPIを呼び出す
• アクセストークンは、通常は「Bearer Token」と
呼ばれる方法でリクエストに含める
– HTTPの「Authorization」ヘッダの値で「Bearer {ア
クセストークンの値}」を指定する
– サンプル
55
GET /friends HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
アクセストークン
- 60. Client(SPA)の実装の例(1/2)
• KeycloakのJSライブラリの場合
60
<html>
<body>
<button onclick="callHello()">call hello</button>
<script src="keycloak.js"></script>
<script>
var keycloak = Keycloak(
{
url: ‘Authorization ServerのURL',
realm: ‘Clientが属するリーム※KEYCLOAKの用語',
clientId: ‘Client Idの値'
}
);
keycloak.init(
{ onLoad: 'login-required'}
).success(function (authenticated) {
・・・
}).error(function (error) {
・・・
});
・・・
ログインしていない場合は、自動的に
Keycloakのログイン画面が表示される
※利用イメージを伝えるのが
目的なので簡略化している
- 61. Client(SPA)の実装の例(2/2)
• Resource ServerのAPIの呼び出し
61
function callHello() {
var url = ‘Resource ServerのAPIのURL';
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
alert('MSG='+req.response);
} else if (req.status == 403) {
alert('許可されてません');
}
}
}
req.send();
}
前スライドで定義した変数から、
アクセストークンを取得している
※利用イメージを伝えるのが
目的なので簡略化している
- 62. Resource Serverの実装例(1/2)
• JavaのSpring Frameworkを利用した場合
• 設定回り
62
@EnableWebSecurity
public class OidcResourceServerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwkSetUri(
"http://localhost:9999/auth/realms/oidc-sample/protocol/openid-connect/certs");
}
}
JWTの電子署名の検証で使用する公開鍵を取
得するためのAuthorization Server上のURL
※利用イメージを伝えるのが
目的なので簡略化している
- 63. Resource Serverの実装例(2/2)
• APIの実装
63
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(@AuthenticationPrincipal Jwt token) {
String msg =
“sub=“ + token.getSubject()
+ " email=" + token.getClaims().get("email")
+ " scope=" + token.getClaims().get("scope");
return msg;
}
}
アクセストークンの情報を
参照できる
※利用イメージを伝えるのが
目的なので簡略化している
- 65. 参考資料の一覧
65
資料 場所
OpenID Connectの仕様 https://openid.net/specs/openid-connect-core-1_0.html
OAuth2.0の仕様 https://tools.ietf.org/html/rfc6749
セキュリティに関するベスト
プラクティス
※インプリシットフローは非
奨励と記載
https://tools.ietf.org/html/draft-ietf-oauth-security-topics-09