Firebase bietet Ihnen die vollständige Kontrolle über die Authentifizierung, da Sie Nutzer oder Geräte mit sicheren JSON Web Tokens (JWTs) authentifizieren können. Sie generieren diese Tokens auf Ihrem Server, geben sie an ein Clientgerät zurück und verwenden sie dann zur Authentifizierung über die Methode signInWithCustomToken().
Dazu müssen Sie einen Serverendpunkt erstellen, der Anmeldedaten wie Nutzername und Passwort akzeptiert und bei gültigen Anmeldedaten ein benutzerdefiniertes JWT zurückgibt. Das von Ihrem Server zurückgegebene benutzerdefinierte JWT kann dann von einem Clientgerät zur Authentifizierung bei Firebase verwendet werden (iOS+, Android, Web). Nach der Authentifizierung wird diese Identität für den Zugriff auf andere Firebase-Dienste wie Firebase Realtime Database und Cloud Storage verwendet. Außerdem ist der Inhalt des JWT im Objekt auth in Ihrer Realtime Database Security Rules und im Objekt request.auth in Ihrer Cloud Storage Security Rules verfügbar.
Sie können ein benutzerdefiniertes Token mit dem Firebase Admin SDK erstellen oder eine JWT-Bibliothek eines Drittanbieters verwenden, wenn Ihr Server in einer Sprache geschrieben ist, die von Firebase nicht nativ unterstützt wird.
Hinweis
Benutzerdefinierte Tokens sind signierte JWTs, bei denen der zum Signieren verwendete private Schlüssel zu einem Google-Dienstkonto gehört. Es gibt mehrere Möglichkeiten, das Google-Dienstkonto anzugeben, das vom Firebase Admin SDK zum Signieren benutzerdefinierter Tokens verwendet werden soll:
- Dienstkonto vom Admin SDK erkennen lassen: Diese Methode kann in von Google verwalteten Umgebungen wie Google Cloud Functions und App Engine verwendet werden. Möglicherweise müssen Sie einige zusätzliche Berechtigungen über die Google Cloud-Konsole konfigurieren.
- Dienstkonto-ID verwenden: Bei dieser Methode werden Tokens mit den von Google verwalteten Schlüsseln des angegebenen Dienstkontos signiert. Sie müssen also keine privaten Schlüssel selbst verwalten. Es wird ein Remote-Webdienst verwendet. Möglicherweise müssen Sie zusätzliche Berechtigungen für dieses Dienstkonto über die Google Cloud-Konsole konfigurieren.
- Dienstkonto-Schlüsseldatei verwenden: Verwenden Sie diese Methode nur, wenn Ihr Code außerhalb einer von Google verwalteten Umgebung ausgeführt wird und Sie keine der oben genannten Methoden verwenden können. Dazu müssen Sie einen langlebigen privaten Schlüssel erstellen, speichern und schützen.
Wir empfehlen die ersten beiden Methoden, da Sie dafür keine Dienstkontoschlüssel herunterladen oder verwalten müssen.
Dienstkonto über das Admin SDK finden lassen
Wenn Ihr Code in einer von Google verwalteten Umgebung bereitgestellt wird, kann das Admin SDK versuchen, automatisch eine Möglichkeit zum Signieren benutzerdefinierter Tokens zu finden:
Wenn Ihr Code in der App Engine-Standardumgebung für Java, Python oder Go bereitgestellt wird, kann das Admin SDK den in dieser Umgebung vorhandenen App Identity-Dienst verwenden, um benutzerdefinierte Tokens zu signieren. Der App Identity-Dienst signiert Daten mit einem Dienstkonto, das von Google App Engine für Ihre Anwendung bereitgestellt wird.
Wenn Ihr Code in einer anderen verwalteten Umgebung bereitgestellt wird (z.B. Google Cloud Functions, Google Compute Engine), kann das Firebase Admin SDK automatisch eine Dienstkonto-ID-Zeichenfolge vom lokalen Metadatenserver abrufen. Die ermittelte Dienstkonto-ID wird dann in Verbindung mit dem IAM-Dienst verwendet, um Tokens remote zu signieren.
Wenn Sie diese Signierungsmethoden verwenden möchten, initialisieren Sie das SDK mit den Standardanmeldedaten für Anwendungen von Google und geben Sie keinen String für die Dienstkonto-ID an:
Node.js
initializeApp();
Java
FirebaseApp.initializeApp();
Python
default_app = firebase_admin.initialize_app()
Go
app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
C#
FirebaseApp.Create();
Wenn Sie denselben Code lokal testen möchten, ohne einen Dienstkontoschlüssel herunterzuladen, melden Sie sich mit Ihren eigenen Nutzeranmeldedaten über die Google Cloud CLI an:
gcloud auth application-default login
Da auf Ihrem lokalen Computer kein Metadatenserver vorhanden ist, kann das Admin SDK dort keine Dienstkonto-ID automatisch erkennen. Geben Sie stattdessen eine Dienstkonto-ID an, wenn Sie das SDK initialisieren, und achten Sie darauf, dass Ihr Nutzerkonto die Rolle Dienstkonto-Tokenersteller für dieses Dienstkonto hat.
Wenn das Firebase Admin SDK eine Dienstkonto-ID-Zeichenfolge ermitteln muss, geschieht dies, wenn Ihr Code zum ersten Mal ein benutzerdefiniertes Token erstellt. Das Ergebnis wird im Cache gespeichert und für nachfolgende Tokensignaturvorgänge wiederverwendet. Die automatisch erkannte Dienstkonto-ID ist normalerweise eines der Standarddienstkonten, die von der Google Cloud bereitgestellt werden:
Wie bei explizit angegebenen Dienstkonto-IDs müssen auch automatisch erkannte Dienstkonto-IDs die Berechtigung iam.serviceAccounts.signBlob haben, damit die Erstellung benutzerdefinierter Tokens funktioniert. Möglicherweise müssen Sie im Bereich IAM und Verwaltung der Google Cloud Console den Standarddienstkonten die erforderlichen Berechtigungen gewähren. Weitere Informationen finden Sie im Abschnitt „Fehlerbehebung“ unten.
Dienstkonto-ID verwenden
Um die Konsistenz zwischen verschiedenen Teilen Ihrer Anwendung zu gewährleisten, können Sie eine Dienstkonto-ID angeben, deren von Google verwaltete Schlüssel zum Signieren von Tokens verwendet werden. Dadurch können IAM-Richtlinien einfacher und sicherer werden. Außerdem müssen Sie keinen Dienstkontoschlüssel herunterladen, speichern oder bereitstellen.
Die Dienstkonto-ID finden Sie in der Google Cloud Console.
Dienstkonto-IDs sind E-Mail-Adressen im folgenden Format: <client-id>@<project-id>.iam.gserviceaccount.com. Sie identifizieren Dienstkonten in Firebase- und Google Cloud-Projekten eindeutig.
Wenn Sie benutzerdefinierte Tokens mit einer separaten Dienstkonto-ID erstellen möchten, initialisieren Sie das SDK wie unten gezeigt:
Node.js
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
Java
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
Python
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
Go
conf := &firebase.Config{
ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
C#
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
Dienstkonto-IDs sind keine sensiblen Informationen und ihre Offenlegung hat daher keine Folgen. Zum Signieren benutzerdefinierter Tokens mit dem angegebenen Dienstkonto muss das Firebase Admin SDK jedoch einen Remotedienst aufrufen.
Außerdem müssen Sie dafür sorgen, dass die Identität, die das Admin SDK für diesen Aufruf verwendet (normalerweise {project-name}@appspot.gserviceaccount.com in der Produktion oder Ihr eigenes Nutzerkonto während der lokalen Entwicklung), die Berechtigung iam.serviceAccounts.signBlob hat.
Weitere Informationen finden Sie im Abschnitt „Fehlerbehebung“ unten.
Dienstkontoschlüsseldatei verwenden
Wenn Ihr Code in einer Umgebung außerhalb von Google Cloud ausgeführt wird, in der keine der oben genannten Methoden verfügbar ist, können Sie das Admin SDK mit einer Dienstkontoschlüsseldatei initialisieren. Weitere Informationen finden Sie in der Anleitung zur Einrichtung des Admin SDK. Bei dieser Methode signiert das Admin SDK benutzerdefinierte Tokens lokal mit dem privaten Schlüssel in der Datei, ohne Remote-API-Aufrufe auszuführen.
Dienstkontoschlüssel sind langlebige Anmeldedaten. Wenn ein Schlüssel geleakt wird, kann jeder, der ihn hat, als Dienstkonto agieren, bis der Schlüssel gelöscht wird. Übertragen Sie Schlüsseldateien niemals in die Versionsverwaltung und verwenden Sie stattdessen die Workload Identity-Föderation, wenn Ihre Umgebung dies unterstützt. Beachten Sie auch, dass einige Organisationen Einschränkungen für Organisationsrichtlinien verwenden, um die Erstellung von Dienstkontoschlüsseln zu verhindern. In diesem Fall müssen Sie eine der anderen Methoden verwenden.
Benutzerdefinierte Tokens mit dem Firebase Admin SDK erstellen
Das Firebase Admin SDK bietet eine integrierte Methode zum Erstellen benutzerdefinierter Tokens. Sie müssen mindestens eine uid angeben. Das kann ein beliebiger String sein, der den Nutzer oder das Gerät, das Sie authentifizieren, eindeutig identifiziert. Diese Tokens laufen nach einer Stunde ab.
Node.js
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
Java
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
Python
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
Go
client, err := app.Auth(context.Background())
if err != nil {
log.Fatalf("error getting Auth client: %v\n", err)
}
token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
log.Fatalf("error minting custom token: %v\n", err)
}
log.Printf("Got custom token: %v\n", token)
C#
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
Optional können Sie zusätzliche Anforderungen angeben, die in das benutzerdefinierte Token aufgenommen werden sollen. Im folgenden Beispiel wurde dem benutzerdefinierten Token ein premiumAccount-Feld hinzugefügt, das in den auth- / request.auth-Objekten in Ihren Sicherheitsregeln verfügbar ist:
Node.js
const userId = 'some-uid';
const additionalClaims = {
premiumAccount: true,
};
getAuth()
.createCustomToken(userId, additionalClaims)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
Java
String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);
String customToken = FirebaseAuth.getInstance()
.createCustomToken(uid, additionalClaims);
// Send token back to client
Python
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
Go
client, err := app.Auth(context.Background())
if err != nil {
log.Fatalf("error getting Auth client: %v\n", err)
}
claims := map[string]interface{}{
"premiumAccount": true,
}
token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
log.Fatalf("error minting custom token: %v\n", err)
}
log.Printf("Got custom token: %v\n", token)
C#
var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
{ "premiumAccount", true },
};
string customToken = await FirebaseAuth.DefaultInstance
.CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client
Reservierte Namen für benutzerdefinierte Tokens
Mit benutzerdefinierten Tokens auf Clients anmelden
Nachdem Sie ein benutzerdefiniertes Token erstellt haben, sollten Sie es an Ihre Client-App senden. Die Client-App authentifiziert sich mit dem benutzerdefinierten Token, indem sie signInWithCustomToken() aufruft:
iOS+
Objective-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Swift
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
Android
mAuth.signInWithCustomToken(mCustomToken)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCustomToken:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCustomToken:failure", task.getException());
Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
}
});
Einheit
auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("SignInWithCustomTokenAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
C++
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
Web
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Web
import { getAuth, signInWithCustomToken } from "firebase/auth";
const auth = getAuth();
signInWithCustomToken(auth, token)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ...
});
Wenn die Authentifizierung erfolgreich ist, wird der Nutzer jetzt mit dem Konto, das durch die im benutzerdefinierten Token enthaltene uid angegeben ist, in Ihrer Client-App angemeldet. Wenn dieses Konto noch nicht vorhanden ist, wird ein Eintrag für diesen Nutzer erstellt.
Wie bei anderen Anmeldemethoden (z. B. signInWithEmailAndPassword() und signInWithCredential()) wird das auth-Objekt in Ihrer Realtime Database Security Rules und das request.auth-Objekt in Ihrer Cloud Storage Security Rules mit der uid des Nutzers gefüllt. In diesem Fall ist die uid diejenige, die Sie beim Generieren des benutzerdefinierten Tokens angegeben haben.
Datenbankregeln
{
"rules": {
"adminContent": {
".read": "auth.uid === 'some-uid'"
}
}
}
Speicherregeln
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /adminContent/{filename} {
allow read, write: if request.auth != null && request.auth.uid == "some-uid";
}
}
}
Wenn das benutzerdefinierte Token zusätzliche Anforderungen enthält, können diese in Ihren Regeln über das Objekt auth.token (Firebase Realtime Database) oder request.auth.token (Cloud Storage) referenziert werden:
Datenbankregeln
{
"rules": {
"premiumContent": {
".read": "auth.token.premiumAccount === true"
}
}
}
Speicherregeln
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /premiumContent/{filename} {
allow read, write: if request.auth.token.premiumAccount == true;
}
}
}
Benutzerdefinierte Tokens mit einer JWT-Bibliothek eines Drittanbieters erstellen
Wenn Ihr Backend in einer Sprache geschrieben ist, für die es kein offizielles Firebase Admin SDK gibt, können Sie benutzerdefinierte Tokens trotzdem manuell erstellen. Suchen Sie zuerst eine JWT-Bibliothek eines Drittanbieters für Ihre Sprache. Verwenden Sie dann diese JWT-Bibliothek, um ein JWT mit den folgenden Anforderungen zu erstellen:
| Benutzerdefinierte Token-Anforderungen | ||
|---|---|---|
alg |
Algorithmus | "RS256" |
iss |
Aussteller | Die E-Mail-Adresse des Dienstkontos Ihres Projekts |
sub |
Betreff | Die E-Mail-Adresse des Dienstkontos Ihres Projekts |
aud |
Zielgruppe | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Ausstellungszeit | Die aktuelle Zeit in Sekunden seit der UNIX-Epoche |
exp |
Ablaufzeit |
Die Zeit in Sekunden seit der UNIX-Epoche, zu der das Token abläuft. Dies kann maximal 3.600 Sekunden später als iat sein.
Beachten Sie, dass damit nur der Zeitpunkt gesteuert wird, zu dem das benutzerdefinierte Token selbst abläuft. Wenn Sie jedoch einen Nutzer mit signInWithCustomToken() anmelden, bleiben er so lange auf dem Gerät angemeldet, bis die Sitzung ungültig wird oder der Nutzer sich abmeldet.
|
uid |
Die eindeutige Kennung des angemeldeten Nutzers muss ein String mit einer Länge von 1 bis 128 Zeichen sein. Kürzere uids bieten eine bessere Leistung.
|
|
claims (optional) |
Optionale benutzerdefinierte Anforderungen, die in die Sicherheitsregeln-Variablen auth/request.auth aufgenommen werden sollen
|
|
Hier finden Sie einige Beispiele für die Erstellung benutzerdefinierter Tokens in verschiedenen Sprachen, die vom Firebase Admin SDK nicht unterstützt werden. In diesen Beispielen werden Tokens lokal mit einem privaten Schlüssel des Dienstkontos signiert. Daher gelten die Sicherheitsrichtlinien für Dienstkontoschlüsseldateien. Wenn Sie keinen privaten Schlüssel verwalten möchten, können Sie stattdessen die Methode signJwt der IAM Service Account Credentials API aufrufen, damit Google die Token-Nutzlast remote signiert. Der Aufrufer benötigt die Rolle Ersteller von Dienstkonto-Tokens für das Dienstkonto.
PHP
Mit php-jwt:
// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;
// Placeholder values. In production, load your service account's email
// address and private key from a secure secret store. Never hard-code
// private keys in source code.
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";
function create_custom_token($uid, $is_premium_account) {
global $service_account_email, $private_key;
$now_seconds = time();
$payload = array(
"iss" => $service_account_email,
"sub" => $service_account_email,
"aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat" => $now_seconds,
"exp" => $now_seconds+(60*60), // Maximum expiration time is one hour
"uid" => $uid,
"claims" => array(
"premium_account" => $is_premium_account
)
);
return JWT::encode($payload, $private_key, "RS256");
}
Ruby
Mit ruby-jwt:
require "jwt"
# Placeholder values. In production, load your service account's email
# address and private key from a secure secret store. Never hard-code
# private keys in source code.
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."
def create_custom_token(uid, is_premium_account)
now_seconds = Time.now.to_i
payload = {:iss => $service_account_email,
:sub => $service_account_email,
:aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
:iat => now_seconds,
:exp => now_seconds+(60*60), # Maximum expiration time is one hour
:uid => uid,
:claims => {:premium_account => is_premium_account}}
JWT.encode payload, $private_key, "RS256"
end
Nachdem Sie das benutzerdefinierte Token erstellt haben, senden Sie es an Ihre Client-App, um sich bei Firebase zu authentifizieren. In den Codebeispielen oben sehen Sie, wie das geht.
Fehlerbehebung
In diesem Abschnitt werden einige häufige Probleme beschrieben, die beim Erstellen benutzerdefinierter Tokens auftreten können, und wie Sie diese beheben können.
IAM API nicht aktiviert
Wenn Sie eine Dienstkonto-ID zum Signieren von Tokens angeben, erhalten Sie möglicherweise einen Fehler wie den folgenden:
Identity and Access Management (IAM) API has not been used in project 1234567890 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
Das Firebase Admin SDK verwendet die IAM API zum Signieren von Tokens. Dieser Fehler weist darauf hin, dass die IAM API derzeit nicht für Ihr Firebase-Projekt aktiviert ist. Öffnen Sie den Link in der Fehlermeldung in einem Webbrowser und klicken Sie auf den Button „API aktivieren“, um sie für Ihr Projekt zu aktivieren.
Das Dienstkonto hat nicht die erforderlichen Berechtigungen
Wenn das Dienstkonto, unter dem das Firebase Admin SDK ausgeführt wird, nicht die Berechtigung iam.serviceAccounts.signBlob hat, wird möglicherweise eine Fehlermeldung wie die folgende angezeigt:
Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.
Weisen Sie dem entsprechenden Dienstkonto die IAM-Rolle Ersteller von Dienstkonto-Tokens zu, um dieses Problem zu beheben. Das verwendete Standarddienstkonto hängt von der Umgebung und der Cloud Functions-Version ab:
- Cloud Functions (1. Generation): Verwendet das App Engine-Standarddienstkonto.
- Cloud Functions (2. Generation): Verwendet das Compute Engine-Standarddienstkonto.
Rufen Sie in der Google Cloud-Konsole IAM und Verwaltung auf.
Klicken Sie auf das Bearbeitungssymbol für das Dienstkonto, das Sie aktualisieren möchten.
Klicken Sie auf Weitere Rolle hinzufügen.
Geben Sie
"Service Account Token Creator"in den Suchfilter ein und wählen Sie es aus den Ergebnissen aus.Klicken Sie auf Speichern, um die Rollenzuweisung zu bestätigen.
Weitere Informationen zu diesem Vorgang finden Sie in der IAM-Dokumentation. Sie können sich auch darüber informieren, wie Sie Rollen mit den gcloud-Befehlszeilentools aktualisieren.
Dienstkonto konnte nicht ermittelt werden
Wenn Sie eine Fehlermeldung wie die folgende erhalten, wurde das Firebase Admin SDK nicht richtig initialisiert.
Failed to determine service account ID. Initialize the SDK with service account credentials or specify a service account ID with iam.serviceAccounts.signBlob permission.
Wenn Sie sich darauf verlassen, dass das SDK eine Dienstkonto-ID automatisch erkennt, muss der Code in einer verwalteten Google-Umgebung mit einem Metadatenserver bereitgestellt werden. Andernfalls müssen Sie bei der SDK-Initialisierung eine Dienstkonto-ID angeben oder das SDK in Nicht-Google-Umgebungen mit einer Dienstkontoschlüsseldatei initialisieren.