web-dev-qa-db-ja.com

Firebase 3でトークンのサーバー側の検証を行うことはまだ可能ですか?

Firebase 3でトークンのサーバー側の検証を行うことはまだ可能ですか?

既存の認証システムを使用して(サービスアカウントを使用して)Golangを実行しているサーバーでカスタムトークン(JWT)を生成します。トークンは、次を使用してiOSクライアントで使用されます

FIRAuth.auth()?.signInWithCustomToken(customToken)

それまではすべて正常に動作します。ただし、次の場所から取得したサーバーにクライアントトークンを渡すと、

FIRUser.getTokenWithCompletion({ token, error in ..})

確認できません。 JWTトークンはRS256を使用して署名されており、認識できないheader.kidがあります。サービスアカウント(カスタムトークンの署名に使用された)からの公開キーは、クライアントトークンを検証しません。クライアントトークンを検証するために公開キーが必要ですか?

JavaまたはJavascriptの "verifyIdToken"呼び出しを使用してクライアントトークンを検証することは可能ですが、標準のJWTライブラリを使用してGolangでこれを実行できるようにしたいと考えています。

これはすべてFirebase 2で正常に機能しました(HS256とFirebaseシークレットを使用)。

42
Tim Rob

簡単な答えはイエスです。完全な答えは、ほとんどの場合、現在、より適切なツールがあることです。そのため、解決しようとしているユースケースに大きく依存します。

新しいSDKバージョンはかなり強力であり、機能を要約するのに優れた仕事をしていません。これは、利用可能なツールとその使用法を対比するのに適した場所のように思えます。最後に、サードパーティ(つまりGo)固有の注意事項について説明します。

クライアント認証に外部認証ツールを使用する

カスタムトークンのミントの主な用途は、LDAPサーバーなど、ユーザーが制御する外部/レガシー認証メカニズムに対してユーザーが認証できるようにすることです。この基本的なプロセスについては、 iOSAndroidWeb をご覧ください。

基本的に、サービスはJWTトークンを作成し、これをクライアントに渡します。クライアントは、指定されたカスタムトークンを使用して検証/認証を行います。

特権ワーカーの認証

サーバープロセスの認証にカスタムトークンを使用する必要はなくなりました。これは、 Firebaseをサーバーに追加する で段階的に説明されているサービスアカウントを作成することによって行われます。完了すると、秘密鍵を含むJSONファイルが作成されます。

次に、firebase.initializeApp()serviceAccount属性を使用してそのJSONを参照することにより、サービスアカウントの資格情報を含めます。それは here で文書化されており、このように見えます(Java version)のリンクを参照してください):

_var firebase = require("firebase");

// Initialize the app with a service account, granting admin privileges
firebase.initializeApp({
  databaseURL: "https://databaseName.firebaseio.com",
  serviceAccount: "./serviceAccountCredentials.json"
});
_

ユーザーのエミュレーションまたはサーバープロセスからのアクセスの制限

ユーザーをエミュレートしたり、サーバープロセスからのアクセスを制限したり(非常に推奨)するのはかなり簡単です。本当にこれのためにカスタムトークンを作成する必要はありません。

これには、databaseAuthVariableOverridedatabase.initializeApp()への呼び出しに追加するだけです。

_firebase.initializeApp({
  databaseURL: "https://databaseName.firebaseio.com",
  serviceAccount: "./serviceAccountCredentials.json",
  databaseAuthVariableOverride: {
    uid: "my-service-worker-or-user-uid"
  }
});
_

セキュリティを介したクライアントIDの検証

まず、クライアントにデータベースへの書き込みを許可し、セキュリティルールを使用してIDを検証することにより、Firebase Databaseを使用している場合、通常はサーバー側の検証を回避できます。サーバーが書き込みに認証を必要とするパスでリッスンする場合、これはサーバーで特別なセキュリティなしで既に解決されています。

これをイベントキューとしてモデル化することにより、シンプルでモジュール式のスケーラブルなサーバーワーカー戦略を作成します。 Node.jsの優れたツールについては、 firebase-queue をご覧ください。それ .xをサポート

サーバー上のクライアントIDトークンの検証

Realtime Databaseを使用しておらず、クライアントトークンを受信する必要がある場合(たとえばREST呼び出し)で、それらが有効であることを確認する場合は、verifyIdToken()説明どおり here これは次のようになります。

_auth.verifyIdToken(idToken).then(function(decodedToken) {
  var uid = decodedToken.sub;
});
_

その後、そのユーザーとして認証してデータベースに書き込み、セキュリティを強化する場合は、上記のEmulating Usersセクションを使用します。つまり、databaseAuthVariableOverrideを適切なuidに設定してinitializeApp()を呼び出します。

initializeApp()を複数回呼び出して、次のようなエラーに遭遇した場合:_Error: Firebase App named '[DEFAULT]' already exists._ initializeApp()呼び出しに2番目の引数を追加することにより、複数のアプリコンテキストを初期化できます。例:database.initializeApp({...}, 'asUser'+uid))そして、firebase.database('asUser'+uid)。ref(...)を使用してそのアプリインスタンスを参照します。複数のアプリインスタンスの使用について詳しくは、 こちらをご覧ください をご覧ください。

上記のリンクで利用可能なJavaコード。 Goおよびその他のサードパーティのソリューションは、以下で説明します。

REST APIで使用するためのトークンの作成

Michael Bleighがこのシナリオを取り上げました here 、これを解決するためのいくつかの代表に値します。

RESTを介したトークンの作成または検証

これはサポートされていません。ごめんなさい。

Golangとその他:今後追加予定

Goトークンのマイニングおよび検証ライブラリに取り組んでいます。また、このためにPythonツールも追加します。このリリース日や球場はありません。当面は、公式を使用せずにクライアントIDトークンを確認したい場合Firebase Node.jsまたはJavaライブラリ(組み込みの検証メソッドを含む))、IDトークン(JWT)が以下に準拠していることを確認する必要があります。

  • デコードされたヘッダーには、_"RS256"_と等しいalg(アルゴリズム)クレームがあります。
  • デコードされたペイロードには、FirebaseプロジェクトIDと等しいaud(オーディエンス)クレームがあります。
  • デコードされたペイロードには、iss(発行者)クレームが_"https://securetoken.google.com/<projectId>"_と等しくなります。
  • デコードされたペイロードには、空でない文字列sub(サブジェクト)クレームがあります。これはそのFirebaseユーザーのuidであることに注意してください。
  • デコードされたヘッダーには、_https://www.googleapis.com/robot/v1/metadata/x509/[email protected]_にリストされている公開キーの1つに対応するkid(キーID)クレームがあります。
  • また、JWTライブラリを使用して、公開鍵でトークンを検証し、公開鍵の対応する秘密鍵でトークンが署名されたことを証明する必要があります。

Goの場合、 _jwt-go_ を使用してクライアントIDトークンをデコードおよび検証できるようです。

51
Kato

Firebaseでは、_custom tokens_の検証が許可されていません。ユーザーがカスタムトークンを使用してサインインすると、_id tokens_の検証が許可されます。私と同じように、Firebaseカスタムトークンを他のサービスに渡してバックエンドで認証する場合、カスタムトークン検証はあなたにあります!また、Googleサービスアカウント_X509 cert_は適切な形式ではありません。これらの\n (new line)区切り文字は、テキストエディターで新しい行に置き換えられません(vimを使用します)。したがって、私がしたことはこれです:

_  val factory = CertificateFactory.getInstance("X.509")
  val certificateFile = this.getClass.getResourceAsStream(Play.current.configuration.getString("firebase.certificate").get)
  val publicKey = factory.generateCertificate(certificateFile).asInstanceOf[X509Certificate].getPublicKey
  val claimBody = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(compactJws).getBody
_
  1. Firebaseのセットアップ中にダウンロードしたJSONで指定されたGoogleサービスアカウントリンクから証明書を取得します
  2. 手動で_\n_を新しい行に置き換えます
  3. JWTライブラリを取得します。この素晴らしいライブラリを使用して検証を行いました Java JWT
  4. 証明書を読み、公開鍵を抽出します。
  5. 公開鍵を使用してトークンを確認します
  6. 1時間のみ有効であるため、トークンを更新する別のAPIがあることを確認してください

お役に立てば幸いです!

0
Richeek