制作中のゲームのキャラクタ/シナリオ投稿機能のためにアカウントシステムを作っていて、その調査過程で集めたメモ。
OpenID ConnectやOAuth2は一応標準規格ではあるものの、結構実装依存のものが多く、結局差分を吸収するためのアカウントサービスは必須という結論に至った。例えば Kloudlessは共通APIを各社向けに提供 している。
この手のサービスはマジで大量にあり、例えばNodejsのライブラリgrantは 200を超えるOAuthプロバイダをサポート (URLとOAuth種別をまとめたjson) していて、 そのPlayGroundでは208種類を試せる 。
更新メモ: https://zenn.dev/okuoku/scraps/32a83075ed0f5c
よみかた
フィールド | せつめい |
---|---|
名称 | サービス名称と、そのブランドガイドライン |
ドキュメント | ID機能の説明へのリンク |
config | WebFingerなディスカバリURI。https://openid.net/specs/openid-connect-discovery-1_0.html |
コンソール | デベロッパコンソールへのリンク。nm-qauth は実際のアプリのIDに置き換える。当然だけどプロジェクト固有のURLは直接見られないので注意
|
アクセストークン寿命 | APIのアクセストークンの寿命と無効化タイミング |
リフレッシュトークン要件 | リフレッシュトークンの払い出される要件。 |
サイレント認証 | IFRAME内でサイレント認証する際の要件 |
CORS要求 | アクセストークンの横流しを行う際にCORSできるか |
アバター | IDにアバター(アイコン)が存在するかどうか。 |
ストレージサービス | 何らかのストレージサービスを提供しているか。GitとかDriveの類い。 |
OpenID Connect
OpenID Connectは結構種類があるが、普通は "Sign in with Google" みたいな感じのボタンで使わせるパブリックサービスが一般的と言える。というか、 通常のシチュエーションでは自前のアカウントサービスを使うメリットは無い 。自前のアカウントサービスは、どうしてもbot用に自動アカウント生成が要るとか、社内で完結したいとか何か理由が有るときにだけ検討すれば良いと思う。
パブリックサービス
パブリックサービスを使うと、ユーザは自身が普段使っているアカウントで他のサービスにもログインできる。つまりユーザは新しいパスワード等を考える必要がなく ブラウザやデバイスがログイン状況を把握しているためインタラクション不要 となる。アプリ提供者としてはパスワード紛失などの対応をする必要がないので、パブリックサービスの利用は双方にメリットがある。
自社IDの価値を高めるのに効果的なため、プラットフォーム各社はパブリックサービスを提供している。ただし、プラットフォーマーが常にオープンなパブリックサービスを持つわけではない; "Sign in with Apple"では専用のSDKが必要で、また利用にはDeveloper programへの参加が必要になる。Facebookやゲーム各社(任天堂、Sony)もパートナー限定のOAuthに絞っている。AmazonもOAuth2のみの提供。
Oktaのドキュメント ( https://developer.okta.com/docs/guides/add-an-external-idp/openidconnect/configure-idp-in-okta/#well-known-configuration-urls ) では、ココに挙げたものの他にIntuitやLine、Salesforceなどを挙げている (EDIT: 直接的な言及は無くなってしまったようだ)。変りダネとしては、 米国政府公式のOIDCプロバイダ なんてものも存在する( https://developers.login.gov/oidc/ )。
Googleアカウント (Android, Chrome)
- 名称 : "Sign in with Google" https://developers.google.com/identity/branding-guidelines
- ドキュメント: https://developers.google.com/identity/protocols/OpenIDConnect
- コンソール : https://console.developers.google.com/apis/dashboard?project=nm-qauth
- config : https://accounts.google.com/.well-known/openid-configuration
- アカウント設定サイト : https://myaccount.google.com/
- ストレージサービス : Google Drive、App Folder有
GMailやその他の都合で大抵の開発者が持っている気がするアカウント。 callbackに .local
のような内部ネットワークが設定できない 、 ユーザconcentページは要審査 など、微妙な制約はある。
Microsoftアカウント (Windows, Xbox)
- 名称 : "Microsoftアカウントでサインイン" https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-add-branding-in-azure-ad-apps
- ドキュメント : https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-protocols-oidc
- コンソール : https://apps.dev.microsoft.com/#/application/ff37068e-ea7e-48bc-b911-2c1abb7db64b (アプリケーションにはUUIDが振られる)
- config : https://login.microsoftonline.com/common/.well-known/openid-configuration
- config(テナント
cltn.onmicrosoft.com
) : https://login.microsoftonline.com/cltn.onmicrosoft.com/.well-known/openid-configuration - アカウント設定サイト : https://account.microsoft.com/
- ストレージサービス : OneDrive
Azure ADとも呼ばれる。特に企業アカウントとの統合に直接使用できるのと、Windowsユーザは無意識のうちにアカウントを作っていることが多いのでゲームでは悪くない選択肢か。
何と 日本語ドキュメントまで有り 、眺める価値があると思う。openid-configurationはissuer部分に {tenantid}
を含む拡張。この tenantid は特定の企業内アカウントをターゲットするといった場合に使用する(全てのMSアカウントを対象にするなら common
が使える)。 ...Discovery仕様ってMSもAuthorに入っているのでこれもlegalなのかも知れない(ちゃんと調べていない)。
2019年 に アプリケーションの登録自体もAzureに移行 し、 apps.dev.microsoft.com
はLegacy扱いになった。新しいポータルはAzureポータル( https://portal.azure.com ) から ID → "アプリの登録"でアクセスできる。
最近の更新で パスワードレス認証に対応 した。Auth0等IDaaSプロバイダでは他に採用しているところもあるものの、大手プラットフォームとしては珍しい。
Sign in with Apple
- 名称 : Sign in with Apple https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple/overview/
- ドキュメント : https://developer.apple.com/sign-in-with-apple/
-
token
エンドポイント仕様 : https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens - 署名鍵(JWKS) : https://appleid.apple.com/auth/keys
- アカウント設定サイト : https://appleid.apple.com/
WWDC 2019で発表されたSign in with Appleは自動生成されるIDなどいくつかの新基軸を盛り込んでおり、認証はJWTを元にしているものの、ログインUI等は専用のJavaScript SDKを使用している。
OpenID財団は Appleへの公開質問状 や、 OpenID Connectとの差分を示したドキュメント を公開して、OpenIDとなるように迫っていた。その後Appleはドキュメント等を修正しOpenID財団は 追加のリリースを出して謝意を表明 している。
Gitlab
- 名称 : なし、マーケティングガイドラインに記述がない https://about.gitlab.com/handbook/marketing/corporate-marketing/
- ドキュメント : https://docs.gitlab.com/ee/integration/openid_connect_provider.html
- コンソール : https://gitlab.com/profile/applications
- config : https://gitlab.com/.well-known/openid-configuration
GitLabはオープンソースでオンプレに立てる選択肢も有る。ここでは GitLab.com インスタンスのリンク。
意外なことにGitHubは同等機能を提供していない(OAuth2のみ)。GitHubはよりプロプライエタリな"Apps"を推しており、そちらはユーザアカウントを使用したアクセスではなく、リポジトリ毎にインストールするスタイルを取っている。
Slack
- 名称 : "Sign in with slack" https://api.slack.com/docs/sign-in-with-slack
- ドキュメント : https://api.slack.com/docs/sign-in-with-slack
- アクセストークン寿命 : 無限
Slackは"Sign in with slack"としてID連携をサポートしている。
従来はなぜかOpenID Connectではなく専用の identity.basic
スコープを使用してユーザ情報を取得させていたが、最近になってOpenID Connectのサポートが追加された。
Twitch
- 名称 : なし。特に公式アセットもない https://www.twitch.tv/p/brand
- ドキュメント : https://dev.twitch.tv/docs/authentication/
- コンソール : https://glass.twitch.tv/console/apps/
- config : https://id.twitch.tv/oauth2/.well-known/openid-configuration
なんで!?とりあえずTwitchにはOpenID Connectによるアカウントシステムが存在する。ドキュメントでも挙げられているように、AWSのCognitoのようなJson Web Tokenを解釈できるシステムとの連携を想定したものだろうか。
Firefox
Firefox アカウントも内部的にはOpenID Connectだが、誰もアプリケーションを登録できずMozilla専用となっている。
自前(IAM、IDaaS)
自前のユーザ基盤について認証部分をアウトソースできるIAMとかIDaaSと呼ばれるカテゴリのサービスが数多く存在する。その多くは "社員" として多くのプライベートユーザを抱える企業向けなので、通常はあんまり意識する機会が無い。
ちなみに、ガートナーはOktaとMSを最大手に分類している( https://www.okta.com/resources/access-management-leader-gartner-magic-quadrant/ )。...要するに通常の大企業であればActive Directory(AD)を使って社員の認証基盤を既に構築しているわけで、そのADのベンダが提供するIDaaSが強くなるのは自然なことと言える。
ガートナーが大手に分類していてココで触れていないプロバイダは:
- IBM(Cloud Identity): https://www.ibm.com/security/cloud-identity
- Oracle : https://www.oracle.com/jp/security/cloud-security/identity-access-cloud/
- Ping identity : https://www.pingidentity.com (NTTcomが代理店をしている)
また、国内で開発/営業しているプラットフォームが星の数ほどある。(e.g. TrustLogin(旧SKUID): https://trustlogin.com/ 、IIJ ID https://www.iij.ad.jp/biz/iid/ )
Okta
- ドキュメント : https://developer.okta.com/docs/api/resources/oidc
- コンソール : https://dev-754062-admin.oktapreview.com/dev/console
- config : https://dev-754062.oktapreview.com/.well-known/openid-configuration
Oktaは最大手IAMベンダで、アプリケーションにOpenID ConnectかSAML2.0基盤を提供する。無料アカウントでは oktapreview.com
ドメインが使用されるが、通常の契約であれば <TENANT名>.okta.com
が使われ、ディスカバリなどもそちらから行える。
OktaはAuth0ほど活発にFOSS活動をしていないが、例えば https://www.oauth.com/ はOktaが提供しているOAuth2の解説サイトとなっている。
最近は営業活動を活発化させていて、 2020年に日本支社を設立、さらにAuth0を買収するなど独立系のベンダとしては独走体制を敷いている。
AWS Cognito
- 概要 : https://aws.amazon.com/jp/cognito/
- ドキュメント : https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-identity-pools.html
- config : https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_Wpq5NQEcL/.well-known/openid-configuration
AWS CognitoはAWSのIDサービスで、電話番号認証といった機能性も統合している。openid
スコープを指定することでID tokenの払い出しも行える。自社のLogin with Amazonはソーシャルログインの1つという位置付けとなっておりそれ以上の特典は提供されていない。
ソーシャルログインに含まれない、SAMLやOpenIDでのサインインはプロ用と位置付けられているためか追加料金が設定されている。無料枠は50名まで。
GCP Identity Platform
AWS Cognitoに相当するサービス。料金や無料枠の範囲もほぼ同一だが、2019年にGAを迎えたばかり。こちらも、Sign in with Googleとの連携は特に特典は設定されていない。
元々はFirebase Authやidentity toolkitとして提供されていたが、Firebase以外のGCP顧客にマーケティングする都合からかFirebaseの一部ではなくGCPの他のサービスと同列に提供されている。
こちらも、Cognito同様ソーシャルログインに含まれないSAMLやOpenIDでのサインインの無料枠は50名未満となっている。
Azure AD
(Microsoftアカウント を参照。)
OneLogin
https://www.onelogin.com/ 。開発者アカウントを持ってないので未調査。
Auth0
- ドキュメント : https://auth0.com/docs/protocols/oidc
- コンソール : https://manage.auth0.com/
- config : https://yuni.auth0.com/.well-known/openid-configuration
Auth0は独立系のIAMベンダで、活発にFOSS活動をしているためそこらじゅうでロゴを見ることになる。
最近Oktaに買収されたが、今のところプロダクトは統合されていない。
自前(オンプレ)
もうKeycloak一択で良いんじゃないかな。。他にもOpenAMとかGluuのような実装は有るが。。OpenAMとKeycloakは国内のベンダがそれなりにサポートしており、特にNRIは両方売っている。
今回のプロジェクトでは、当初Keycloakをカスタマイズして開発者アカウントはそちらに集約する方向にしていた。ただ開発コストがちょっと高いのと、アバターやその他のセルフサービス類の統合のために自前のアカウントサービスを実装する必要が出てきてしまったので放棄してしまった。
Keycloak
- 本家 : https://www.keycloak.org
- config(
stripe.local
、master
) : https://stripe.local/kc/realms/master/.well-known/openid-configuration - ref: OpenID Connectを使ったアプリケーションのテストのためにKeycloakを使ってみる
KeycloakはJava製のIAM製品で、Red Hatは自社のRed Hat Single Sign-On 製品のコアとして使用している。
OpenID Connect実装としては至って普通。内蔵のID/Passwordストアの他に、LDAPやKerberos、ソーシャルログインもサポートしている。インストールや管理もわかりやすく、テスト用にはおすすめ。
Keycloakは認証領域を"Realm"と呼ばれる単位で扱う。インストール時に自動的に master
realmが作成されるが、OpenID Connect的な意味のIssuerにもこのRealmが入ることになる。
OpenID Connect へのトランスレータ
既存の認証システムをOpenID Connectに変換できるアダプタ。このカテゴリは色々有っても良いんじゃないかという気がしているが、現状ではdexくらいしか見つけられていない。
dex
- ドキュメント : https://dexidp.io
dex はフェデレーションに特化したOpenID Connectプロバイダで、既存のLDAP(Active Directory)やOpenID Connect認証基盤をサブセットしてローカルサービスに使うのに向いている。
基本的にはアクセストークンの横流し機能が無いため、ソーシャルログインしたプロバイダのAPIを直接呼ぶ方法が無い。
Dexは従来CoreOSの一部だったが現在はCNCFのSandboxプロジェクトに移行している。
まだアルファ版のAuthProxy( https://github.com/dexidp/dex/blob/master/Documentation/connectors/authproxy.md )は興味深い機能で、HTTPヘッダ X-Remote-User
に設定したユーザ名を sub
とするようなID Tokenを発行するだけの機能になっている。これを使用すると、Basic認証やその他のcallback認証をOpenID Connect仕様のRPに接続することができる。
自作する
ぶっちゃけOIDC OPの自作は止めといた方が良い。本当にマジでやりたい場合は oidc-provider
( https://github.com/panva/node-oidc-provider/ ) のnpmモジュールが機能的に良く揃っている。
- 作例: "悪い" OpenID Connect OP を作る - わざと全員をAuthenticateしたり、異常なJWTを返す
うちではOIDC / OAuth2は人間用と決めて、内部の認可サービスではJWTの発行しなおしをして各APIエンドポイントで検証する方向とした。
OpenID Connect っぽい奴
("Sign in with Apple" は以前ココに分類していたが、だいぶOpenID Connectに近付いたのでパブリックサービスに移動した。FirebaseもIdentity Platformに移動したいけど現在評価中。)
Firebase authentication
- ドキュメント : https://firebase.google.com/docs/auth/?hl=ja
- config : https://securetoken.google.com/nm-qauth/.well-known/openid-configuration
GoogleのFirebase authenticationはJWTベースのIDトークンを払い出し、検証用の鍵はOpenID discoveryで取得できるJWKSで公開されている。実際のアプリケーションでは、上記の nm-qauth
部分はそれぞれのアプリケーションIDに置き換わる。
OpenID Connect仕様のAuthorize / tokenエンドポイントは提供されないので、自前で用意する必要がある。...まぁ専用のFirebaseUI Authを使うべきだろう。
OAuth系統
OAuth系統で纏めてしまっているが、OAuth1とOAuth2は別物なので注意。OpenID Connectと異なり、OAuthはAPIのアクセス制御用Tokenを配るところまでしか面倒を見てくれないため、ユーザ情報の取得はプロバイダ毎のAPIを呼び出して実装する必要がある。
有名どころのプロバイダしか使わないなら、Hello.js( https://adodson.com/hello.js/ )のようなwrapperを使うと良いかもしれない。
OAuth1
いまどきOAuth1はほぼ使われておらず、ほぼTwitter専用と言って良いのではないだろうか。
- ドキュメント : https://developer.twitter.com/en/docs/basics/authentication/overview/oauth
- コンソール : https://developer.twitter.com/en.html
- リクエスト署名:
HMAC-SHA1
現在はアプリケーションの説明が必須になったり、かなり制約が増えてしまっている。リクエストの署名アルゴリズムは HMAC-SHA1
のみ。
ちなみにユーザコンテキストを伴わないアクセスはOAuth2をモデルにしている。
現在OAuth2サポートがbeta入りしている。ref: TwitterのOAuth2.0 Betaためしてみた! 。
JIRA / Confluence
- ドキュメント : https://developer.atlassian.com/server/jira/platform/oauth/
- リクエスト署名 :
RSA-SHA1
https://github.com/floralvikings/jira-connector/blob/85b931d363223fff830bfe3a7238ce15cf66cb23/lib/oauth_util.js#L116
企業内バグトラッカ/Wikiとしてまだまだ人気のJIRAおよびConfluenceは、現在もOAuth1.0aのみのサポートとなっている。(同じAtlassianのBitbucketやクラウド版はOAuth2をサポートしている。またオンプレミス版も ロードマップには対応を掲げている がオンプレミス版の扱いを大幅に縮小したため今後は何とも言えない。)
Wrapperとしてはnpmのjira-connectorが有る。リクエストの署名アルゴリズムは RSA-SHA1
のみ。このため、この手のAPI仕様としては珍しくShared secretの代りにRSA公開鍵を登録する必要がある。
JIRAやConfluenceのローカルインスタンス自体は有償だが、SDK( https://developer.atlassian.com/server/framework/atlassian-sdk/ )にテスト用のインスタンスが同梱されているため、それらを使用して開発することができる。また、クラウド版はAtlassianアカウントを持っていれば無料で使用できる。
OAuth2
とにかくメッチャいっぱいある。今回はプロジェクトの目的に合わせて、ゲームまたはソフト開発でよく使われるサービスに絞っている。
GitHub
- ドキュメント : https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
- アクセストークン寿命 : 無限
GitHubにはオンプレミスで使用できるGitHub Enterpriseも有るが、そちらもOAuth2をサポートしており同様の連携を社内アプリケーションに展開できるように配慮している。
OAuth的なアクセストークンを直接発行する手法として"Personal Access Token"を用意しており、OAuth的なスコープと紐付いたアクセストークンをWebページ上で発行できる。主にコマンドラインクライアント等との連携を想定した仕様。
SSH公開鍵がスコープされていない等、大手サービスとしては疑問の残る仕様が散見される。
GitHubはMSに買収されており、GitHubアカウントはMSアカウントのサインインに使用できる。しかし、GitHubのAPIは、MS製の同様のサービスであるAzure DevOpsとは大幅に異なる。
BitBucket
- ドキュメント : https://developer.atlassian.com/cloud/bitbucket/oauth-2/
- アクセストークン寿命 : 60分
GitHubとは異なり、Implicit grantをサポートしている。また、通常のGrant typeではリフレッシュトークンが振り出され、アクセストークンには60分の寿命が設定されている。独自拡張のJWT grant typeはAtlassianクラウドとの連携を想定したもので、JWT tokenとアクセストークンの交換を行うことができる。
Amazon
- 名称 : "Login with Amazon" https://developer.amazon.com/ja/docs/login-with-amazon/button.html , https://developer.amazon.com/ja/docs/login-with-amazon/brand.html
- ドキュメント : https://developer.amazon.com/ja/docs/login-with-amazon/documentation-overview.html
AmazonのLogin with AmazonはAmazonの顧客基盤をWebサイトに導入する目的で提供されている。例えばAmazon Pay(Amazonの通販アカウントを直接使用した決済)などの統合を行うための起点となっている。当然、AWS Cognitoでソーシャルログインの1つとして使用できる。
珍しく標準準拠のDevice Flowを提供している。
Discord
- 名称 : なし https://discordapp.com/branding
- ドキュメント : https://discordapp.com/developers/docs/topics/oauth2
- アクセストークン寿命 : 10080分 (1週間)
Discordはゲーミングコミュニティをターゲットとしたテキスト + ボイスチャットプラットフォームで、それなりに普及している。
アクセストークンは1週間と絶妙な長さで、基本的には横流しを想定していないデザインに見える。
最近 大規模なbotからのメッセージ取得を廃止する 方針を発表して割と荒れている。例えばPythonライブラリのdiscord.pyはこれによって開発を終了してしまった。
Dropbox
- 名称 : なし https://www.dropbox.com/branding
- ドキュメント : https://www.dropbox.com/developers/reference/oauth-guide
- APIドキュメント : https://www.dropbox.com/developers/documentation/http/documentation
- コンソール : https://www.dropbox.com/developers/apps
- アクセストークン寿命 : 無限 (https://www.dropbox.com/developers/support → "Do access tokens expire?")
Dropboxは言わずと知れたオンラインストレージサービスで、それなりに普及している。が、他のストレージサービスと違ってDropboxは アクセストークンに寿命が設定されていない 。DropboxはApp folderの概念があり、app folderに対して発行されたアクセストークンは他のフォルダにアクセスできない仕様になっている。
ユーザ数の多い(50+名)アプリは審査制となっている。
APIドキュメントでは明示的にDropboxをIdPとして使うなと書いている:
Note: OAuth is an authorization protocol, not an authentication protocol. Dropbox should not be used as an identity provider.
Slackは"sign in with slack"でOAuthでもIdPとしての機能性を提供していたのと対照的と言える。
box
- 名称 : なし https://developer.box.com/docs/branding-guidelines
- ドキュメント : https://developer.box.com/reference#oauth-2-overview
- コンソール : https://app.box.com/developers/console
- アクセストークン寿命 : 60分
boxもメジャーなオンラインストレージサービスの一で、特に企業や大学で人気がある。
boxはOAuth2サービスとしては珍しくトークンの横流しを想定したデザインになっており、特徴的なダウンスコープ(既存のアクセストークンを使用して、より権限の少いトークンを発行する)を独自のAPIでサポートしている。また、BitBucketのようなJWT認証もサポートしている。
アプリケーションの追加は通常のアカウントで可能だが、 何故かアプリケーションの削除は2要素認証が必須 となっている。何故。。?