Self-Issued OP 確認してみた @ Recruit ポンパレ
先日、2018/3/23金に開催された、OpenID Technight #15に参加した際、そこで紹介のあった OpenID Connect Self-issued OP について、下記にメモ書きしていたのですが、
OpenID Connect Self-issued OP概要 ~OpenID Technight #15より~
https://qiita.com/SAM-l/items/93b56c6061cfbb6653ec
その際「iPhoneのポンパレモールアプリで実際に動いている様子を見れるってよ」
ということだったので、実際にポンパレモールでやりとりされている電文を覗いてみました
以下、覗いた結果です。
環境情報
-
端末
- iOS 11.3
- ポンパレモールアプリ 2.1.7
-
電文の確認に使ったもの
- Mac OS High Sierra 10.13.4
- Burp Proxy 1.7.33
-
確認日
- 2018年4月24日(火)
概要シーケンス
やりとりされている内容を見る限り、ざっくり下記のようなシーケンスになっている事が確認できました。
- 青色部分
- リクルート内の共通OP(リクルートポイント)での認証&認可のフロー
- 赤色部分
- Self-issued OPもどきのフロー
以降、詳細を記しますが、
- パラメータを見やすくするため本来存在しない改行をいれてます
- 「*****」でマスクされている箇所には実際は文字列が入っていました
ご了承ください。
1. ボタン押下
- ポンパレモールのアプリを開き、「次へすすむ」ボタンを押下する
- 一度ログインしてしまっていたので、「*****でログインする」の文言が表示されているもよう
2. 共通OPにAuthZ Req
- ボタンを押下すると、送付されたリクエストが下記
-
code_challenge
やcode_challenge_method
が送付されており、PKCEに対応している事がわかる -
thumbprint
で送られている値は、「5. Self-issued OP AuthZ Res」で送付されるid_token
のsub
の値
AuthZReq
POST /member/OIDCLogin/?
scope=openid%20r_profile%20r_email%20r_phone%20r_address%20r_ml_magzn%20r_etc&
state=*****&
client_id=*****&
response_type=code&
login_hint=*****&
redirect_uri=https://mypage.ponparemall.com/member/distributionOidc/?appCd=2&
sc_ap=1&
sc_vid=***** HTTP/1.1
Host: point.recruit.co.jp
Content-Type: application/x-www-form-urlencoded
code_challenge=*****&
code_challenge_method=S256&
thumbprint=*****
3. Self-issued OP に AuthZ Req
- Self-issued OP に対応しているアプリであることを確認
- 判断基準はよくわかりません
- 確認できたら Self-issued OP に AuthZ Req
- Self-issued OP 未対応のアプリではおそらく下記の流れ
- AuthZ Req を受けて「リクルートポイント」が認証画面を出す
- ID/PWDで認証を行う
- 「6 .共通OP AuthZ Res」へ
- カスタムスキーム経由ではなく「https://point.recruit.co.jp/member/OIDCLogin/verify 」へのリクエストをSelf-issued OP へのAuthZ Reqと判断しているもよう
SIOP_AuthZReq
HTTP/1.1 302 Found
Location: https://point.recruit.co.jp/member/OIDCLogin/verify/?
state=*****&
nonce=*****&
scope=openid&
response_type=id_token&
key_state=registered&
client_id=https%3A%2F%2Fpoint.recruit.co.jp%2Fmember%2FOIDCLogin%2Fverify%2F
4. 認証
- 初回はID/PWDで認証
- 以降は画面遷移のみでユーザの操作なし
5. Self-issued OP AuthZ Res
- 以前やりとりした証明書情報で生成されたid_tokenが発行される
SIOP_AuthZRes
GET /member/OIDCLogin/verify/?id_token=*****&state=***** HTTP/1.1
Host: point.recruit.co.jp
- 実際のid_tokenの内容はこんな感じ
id_token(header)
{
"typ" : "JWT",
"alg" : "RS256"
}
id_token(body)
{
"iat" : 1524571670,
"r_terminfo" : "iPhone9,2",
"iss" : "https:\/\/self-issued.me",
"sub" : "*****",
"sub_jwk" : {
"kty" : "RSA",
"n" : "*****",
"e" : "AQAB"
},
"aud" : "https:\/\/point.recruit.co.jp\/member\/OIDCLogin\/verify\/",
"exp" : 1524573470,
"nonce" : "*****"
}
6. 共通OP AuthZ Res
- Self-issued OP からの
id_token
の検証をもって、認証完了、レスポンスを返却 - リダイレクトが以下の通り何回も走ってた
AuthZRes-1
HTTP/1.1 302 Found
Location: https://point.recruit.co.jp/member/twoStepAuth/oidcLoginAuth/?
scope=openid+r_profile+r_email+r_phone+r_address+r_ml_magzn+r_etc&
auth_transct_id=*****&
response_type=code&
state=*****&
insertion_flg=&
prompt=&
nonce=&
redirect_uri=https%3A%2F%2Fmypage.ponparemall.com%2Fmember%2FdistributionOidc%2F%3FappCd%3D2
AuthZRes-2
HTTP/1.1 302 Found
Location: https://point.recruit.co.jp/member/OIDCConsent/?
scope=openid+r_profile+r_email+r_phone+r_address+r_ml_magzn+r_etc&
auth_transct_id=*****&
response_type=code&
redirect_uri=https%3A%2F%2Fmypage.ponparemall.com%2Fmember%2FdistributionOidc%2F%3FappCd%3D2&
state=*****&
sc_ap=1&
client_id=*****&
sc_vid=*****
- ようやく
code
が渡された
AuthZRes-3
HTTP/1.1 302 Found
Location: https://mypage.ponparemall.com/member/distributionOidc/?
appCd=2&code=*****&
state=*****&
sc_ap=1&
sc_vid=*****
7. 共通OPに Token Req
- AuthZCode で AccessToken要求
- でも
grant_type
もredirect_uri
もないね独自仕様かな
- でも
-
PKCE に対応しているため、
code_verifier
の送付必要- でもパラメータ名がCamelCaseだね
TokenReq
POST /1_1_0/accessTokenIssueOidc/ HTTP/1.1
Host: auth.api.ponparemall.com
appCd=2&
autoLoginFlg=1&
code=*****&
codeVerifier=*****&
deviceUUId=*****&
format=json&
key=*****
8. 共通OP Token Res
- 要求したscopeにアクセスするためのAccessTokenが発行される
-
rLoginHint
の値には「5. Self-issued OP AuthZ Res」で送付されるid_token
のsub
の値が -
rUserDisplayName
の値にはログイン時に使ったメールアドレスが - Token Responseも何かちょっと違うね
TokenRes
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"authInfo":
{
"accessToken":"*****",
"accessTokenRefreshExpireTs":"2018/04/24 21:37:50",
"secretToken":"*****",
"rCapMemberId":"*****",
"rUserDisplayName":"*****",
"rLoginHint":"*****"
}
}
おわりに
ところどころ、Recruitさま独自仕様っぽいものが発見されて面白かったです。
お買い物をするとインタラクション必須となるフローが走るとのことだったのでそちらも試したいところですが、明日早朝からロケなのでここで一旦中断します