nappsについてのメモ

一部界隈で最近よく名前を聞くnappsについて調べてみたので、自分の理解のためにまとめます。

nappsとは

nappsとはNative Applications WGのことでモバイルのネイティブアプリでのSSOをOpenID Connectで実現するprofileを策定しています。(native(n) applications(apps)でnappsなんですかね?)

nappsでは、例えばスマートフォン複数のネイティブアプリがインストールされていて、かつそれらがOAuthによるリソースアクセスとOpenID Connectによる認証を行う場合、複数のネイティブアプリ全てで認証と認可の管理が必要になってユーザビリティ的に厳しいよねという問題を解決するとしています。各アプリで認証するとかなっているとユーザビリティ的にもセキュリティ的にもつらいですね。

で、どうやってこの問題を解決するかというと、あるアプリをToken Agent(TA)と呼ばれる他のアプリの代わりにtokenを取得する特別なclientとし、TAを経由して他のアプリはtokenを取得するとしています。このTAによってtokenのprovisioningとSSOを実現します。TAでのみ認証させるようにすることでフィッシング防止にもなるかなーと思います。

リポジトリを見た感じ、nappsでは今のところ仕様は2つあるみたいです。

  • OpenID Connect Native Application Token Agent Core 1.0
  • OpenID Connect Native Application Token Agent API Bindings 1.0

1つがcoreとなる仕様で、もう1つはTAと他のアプリの間でのやりとりに関する仕様のようです。

語彙

OpenID Connectの語彙に加えて、いくつか語彙が加わっています。

  • Token Agent (TA)
    • その他のアプリに変わってaccess tokenなどを取得するアプリのことで、Authorization Serverごとにユーザーはこのアプリでのみ認証をします
  • Primary Token
    • TAに発行されるaccess token, refresh token, id_tokenのこと
  • Secondary Token
    • その他のアプリに発行されるaccess tokenのこと
  • AppInfo Endpoint
    • TAがアプリのメタデータを取得するエンドポイントで、取得されたメタデータはその他のアプリのSecondary Tokenを取得するために使われます

フロー

Native Application Token Agent Coreでは以下のようなフローが想定されています。

f:id:bang_yy:20141102031557j:plain

省略して書いてありますが1,2は普通のOpenID Connectのフローです。このステップではTA自身に発行されるPrimary Tokenを取得します。ただし、1,2のOpenID ConnectのフローはAuthorization Flowでなければならず、Authorization Endpointではresponse_typeにcodeを、scopeにopenidとnappsという文字列を含めるようにします。napps scopeはTAがSecondary Tokenの取得に使用できるtokenを要求していることを示しています。

3,4でTA以外のアプリのSecondary Tokenを取得しています。TAからのリクエストは以下のようになります。Secondary Tokenはrefresh tokenを使って取得します。scopeに指定する値は後で出てくるAppInfo Endpointで得られるアプリごとの文字列で、scopeの値でSecondary Tokenを発行するアプリが指定されます。

POST /as/token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=refresh_token&
  refresh_token=qANLTbu17rk17lPszecHRi7rqJt46pG1qx0nTAqXWH&
  scope=urn:oauth:boxx

レスポンスとしてaccess tokenもしくはid_tokenを受け取ります。id_tokenを受け取った場合はさらにid_tokenとaccess tokenを交換することになるのですが、そのケースについてはTBDとなっていました。アプリがTAにSecondary Tokenを要求する部分についてはapi bindingsで規定されるとのことです。

5でTokenの受け渡しをします。ここについてもapi bindingsで規定されるようです。

6でアプリからResource ServerにSecondary Tokenを使ったAPIリクエストをしています。さらに、このリクエストを受けて、Resource Serverは7のaccess tokenの検証を行います。access tokenの検証を行います。検証の方法は規定されていませんが、tokenの検証をAuthorization Serverに依頼したり、tokenのsignatureをResource Server内で検証するなどが例に出ています。

AppInfo Endpoint

また、Native Application Token Agent CoreではAppInfo Endpointというエンドポイントが存在しています。このエンドポイントにリクエストすることで、TAを利用してaccess tokenを取得するアプリのメタデータを取得できます。AppInfo Endpointへのリクエストはaccess_tokenとschemeの2つのパラメータを指定して、GETもしくはPOSTでリクエストします。access_tokenにはTAが取得したaccess_tokenを、schemeには"napps"という文字列を指定します。GETだとこんな感じになります。

GET /appinfo?scheme=napps HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG

レスポンスはjsonで、以下のようなメタデータが返ります。

{
    "schema": "http:openid.net/schema/napps/1.0",
    "branding": {
        "companyname": "ABS",
        "companyiconurl": "http://www.ABS.com/logo.gif"
    },
    "apps": [
            {
                "name": "Boxx",
                "type": "native",
                "scope": "urn:oauth:boxx",
                "default_scopes": ["read" , "admin" ],
                "icon_uri": "http://www.example.com/pic.png",
                "custom_uri": "app1://callback-uri/"
            },
            {
                "name": "test1",
                "type": "web",
                "scope": "urn:oauth:test1",
                "default_scopes": ["urn:oauth:web-sso"],
                "icon_uri": "http://www.example.com/pic.png",
                "web_init_ep": "http://init-sso.example.com/start"
        ]
}

レスポンスの中身は以下のような内容になっています。

  • name
    • アプリの名前
  • type
    • アプリのタイプ(nariveかwebとなります)
  • scope
    • Secondary Tokenを取得する際に指定するscopeの値
  • default_scopes
    • アプリから明示的な指定がない場合、Secondary Token取得時にscopeパラメータに加える値
  • custom_uri
    • TAからアプリに戻る際のcustom scheme URI

AppInfo Endpointで得られるメタデータは、ランチャーのようにしてユーザーにアプリの情報を表示するのに使用したり、Secondary Tokenを取得する際に使われます。

感想

いろいろ資料を見ているとエンプラ向けの仕様なのかな?と思いました。LINEやFacebook的な、母艦となるアプリケーションが存在する場合でも有効そうなフローだとは感じます。