OpenID Connect Self-issued OP概要 ~OpenID Technight #15より~

# OpenID Connect Self-issued OP概要

先日、2018/3/23金に開催された、OpenID Technight #15に参加した際のできごと、完全に頭の中から消えてしまう前にメモ残しておこうと思います。
ということで、リクルートさんがお話しされていた、OpenID Connect Self-issued OPのお話。

OpenID Connectは知っている前提でのメモになりますので、「OpenID Connectってなに？」っていうのは他の方の記事等を参考に・・・。

## OpenID Connect Self-issued OPって？

### Self-issued OP？
OpenID Connect の仕様で定義されてるあれです。
:point_right: http://openid.net/specs/openid-connect-core-1_0.html#SelfIssued

"OP（OpenID Provider）" は、OpenIDに対応してる認証プロバイダのことで
認証プロバイダは、「Googleでログインする」の場合はGoogleがそれですね。

OpenID Connect では 認証プロバイダが発行した id_token で認証連携するので、"Self-Issued" な id_token を発行する "OP" ってことだと思います。
ざっくり言えば、ユーザ自身が使っているクライアントが id_token を発行するよって感じかな。


### ふつうのOpenID Connectとなにが違う？
Flowは完全に、Implicit Flowです。
Implicit Flowで自己署名のid_tokenだけ発行するやつ。みたいなかんじ。

ふつうのImplicit Flowとの違いは、

 - AuthorizationEndpointは ```openid://``` カスタムスキーム
 - Provider ID（Tokenのissuer）は ```https://self-issued.me```
 - client_id は ```redirect_uri``` の値を設定
 - id_tokenの ```sub```（ユーザ識別子がはいるとこ）には、署名した**証明書の拇印**をBase64urlエンコードしたもの が入る

ってところでしょうか。

### 概要フロー
Self-issued OP なスマホアプリを作ったとしたら、こんな感じになるかと思います:point_down:
もちろん、app=Self-issued OPでも:o:

![Self-issued OP-1.png](https://qiita-image-store.s3.amazonaws.com/0/246440/644dac72-67c2-fdca-41cf-7a57f8838078.png)



### id_tokenの例
[OIDC仕様中の例](http://openid.net/specs/openid-connect-core-1_0.html#SelfIssuedValidation)を抜粋:point_down:

```json
{
   "iss": "https://self-issued.me",
   "sub": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
   "aud": "https://client.example.org/cb",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "sub_jwk": {
     "kty":"RSA",
     "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
     4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
     tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
     QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
     SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
     w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
     "e":"AQAB"
    }
  }
```
```sub_jwk``` にはいってるのは公開鍵情報。
id_token受け取った側はこの公開鍵で署名検証を行います。


### 仕様範囲外のこと

決めなきゃいけないんけど、仕様の範囲外のこともいくつかあります。
下記なんかがそう。

- 発行した秘密鍵をクライアント側でどう安全に保管するか。
- 保管する秘密鍵は１つのみか。あるいは複数保存して複数アカウントに対応可能にするか。
- Credentialとしてなにをユーザに提示させるのか、それをどのように検証するのか。
- id_token 受け取る側としては、token検証できたところで得られる識別子は証明書の拇印。それを既知の識別子とどう結びつけるか。初回連携のタイミングは？ １-多、多-1の可否は？ など。


## Recruitさんでの使われ方

### OpenID Tech Night vol.15 での資料
![TechNight15_Recruit.png](https://qiita-image-store.s3.amazonaws.com/0/246440/b75e2317-7b90-ae58-7037-4d1427822c94.png)
https://speakerdeck.com/rtechkouhou/openid-connect-self-issued-idpwoying-yong-sitasingle-sign-onfalseshi-zhuang

### 特徴は？
iOSとAndroidで若干異なるようで、上半分はiOSアプリでの取り組みですが、スライドからの抜粋だとこちら。
![TechNight15_Recruit-02.png](https://qiita-image-store.s3.amazonaws.com/0/246440/bd1e6365-a2bb-dbf5-fd5f-fade5f928264.png)

他スライドで触れられていたこともざっくりまとめると

- 秘密鍵の安全な管理方法 → Shared KeyChainを利用
    - 同一版権元で共有可能（リクルートのアプリ間で鍵を共有できる）
    - 端末アンロックと連動可能（Touch IDとかも使える）
- 独自定義のACR(Authentication Context Class Reference)や AMR(Authentication Methods References)を活用
    - ユーザとのインタラクションが必須な場合に、秘密鍵を持ってるからといってスルっと抜けてしまわないよう工夫されている
- リクルートの共通認証サービス（Recruit ID)が、OpenID Connect対応のOPであり、そこでの認証方法の１つの手段としてSelf-Issued OPを活用
    - Recruit IDは、OPであり、Self-Issued OPを使う時にはRPになる
    - Recruit IDでは、さらにOAuth 2.0 の拡張仕様 PKCE（Proof Key for Code Exchange/"ぴくしー"と読む。OAuthの妖精さん）を採用し、認可コード横取り攻撃対応でセキュリティ強化
    - Self-Issued OPを使う＝スマホアプリ＝Public Client＝client_secret持ってないやん:exclamation: なので、その際に懸念される「認可コード横取り攻撃」の対策がきちんとなされている

### 実際どのアプリで動いている？

ずばり、[ポンパレモール](https://itunes.apple.com/jp/app/%E3%83%9D%E3%83%B3%E3%83%91%E3%83%AC%E3%83%A2%E3%83%BC%E3%83%AB/id872837743)だそうです:bulb:
![ポンパレモール.png](https://qiita-image-store.s3.amazonaws.com/0/246440/59793c9b-42d5-04f8-7847-2c72ad165fd1.png)

 しかも、お買い物したら、Touch IDのフローが動くらしいですってよ:bulb::bulb:


## おわりに
ユーザ自身の端末が、認証サーバになり、リソースサーバになり、
コンテキストによって認証/属性の組み合わせを自由に選択して使い分けができるようなもの！ という
10年くらい前にぼんやりあったものが現実みを帯びてきて懐かしくなりました。

私がまだ社会人になりたてくらいの頃だったと思います、[Liberty Alliance Day 2007](http://www.projectliberty.org/news_events/events/liberty_alliance_deplopyment_workshop_day_2007_open_and_convergence_toward_new_stage_of_identity_management/) というイベントがありまして。

まだOpenIDもAuthentication2.0の仕様が出たてくらい？・・・記憶が定かじゃないですが、
Liberty Allianceでの、SSOの標準仕様といったら、SAML([Security Assertion Markup Language](https://wiki.oasis-open.org/security/FrontPage)) なので、
OpenIDではなく、SAMLメインでした。
デモ展示を行なっているブースがいくつかあり、
その頃から、SAMLのIdPを携帯端末に立てて、「認証を自分の携帯に集約:point_up:」といったことがされてたんです。
スマホじゃなくてガラケーの時代に。

それがデモじゃなくて、実サービスで動いてる:bangbang:
時代が追いついてきた:bangbang:

私の頭も置いてけぼりにされないよう、これからも追いついて行きたいと思います:girl::girl: