53
53
METADATA_SERVICE_URL = ('http://metadata.google.internal/computeMetadata/v1/instance/'
54
54
'service-accounts/default/email' )
55
55
56
+ # Emulator fake account
57
+ AUTH_EMULATOR_EMAIL = '[email protected] '
58
+
59
+
60
+ class _EmulatedSigner (google .auth .crypt .Signer ):
61
+ key_id = None
62
+
63
+ def __init__ (self ):
64
+ pass
65
+
66
+ def sign (self , message ):
67
+ return b''
68
+
56
69
57
70
class _SigningProvider :
58
71
"""Stores a reference to a google.auth.crypto.Signer."""
@@ -78,6 +91,10 @@ def from_iam(cls, request, google_cred, service_account):
78
91
signer = iam .Signer (request , google_cred , service_account )
79
92
return _SigningProvider (signer , service_account )
80
93
94
+ @classmethod
95
+ def for_emulator (cls ):
96
+ return _SigningProvider (_EmulatedSigner (), AUTH_EMULATOR_EMAIL )
97
+
81
98
82
99
class TokenGenerator :
83
100
"""Generates custom tokens and session cookies."""
@@ -94,6 +111,8 @@ def __init__(self, app, http_client, url_override=None):
94
111
95
112
def _init_signing_provider (self ):
96
113
"""Initializes a signing provider by following the go/firebase-admin-sign protocol."""
114
+ if _auth_utils .is_emulated ():
115
+ return _SigningProvider .for_emulator ()
97
116
# If the SDK was initialized with a service account, use it to sign bytes.
98
117
google_cred = self .app .credential .get_credential ()
99
118
if isinstance (google_cred , google .oauth2 .service_account .Credentials ):
@@ -286,20 +305,22 @@ def verify(self, token, request):
286
305
verify_id_token_msg = (
287
306
'See {0} for details on how to retrieve {1}.' .format (self .url , self .short_name ))
288
307
308
+ emulated = _auth_utils .is_emulated ()
309
+
289
310
error_message = None
290
311
if audience == FIREBASE_AUDIENCE :
291
312
error_message = (
292
313
'{0} expects {1}, but was given a custom '
293
314
'token.' .format (self .operation , self .articled_short_name ))
294
- elif not header .get ('kid' ):
315
+ elif not emulated and not header .get ('kid' ):
295
316
if header .get ('alg' ) == 'HS256' and payload .get (
296
317
'v' ) == 0 and 'uid' in payload .get ('d' , {}):
297
318
error_message = (
298
319
'{0} expects {1}, but was given a legacy custom '
299
320
'token.' .format (self .operation , self .articled_short_name ))
300
321
else :
301
322
error_message = 'Firebase {0} has no "kid" claim.' .format (self .short_name )
302
- elif header .get ('alg' ) != 'RS256' :
323
+ elif not emulated and header .get ('alg' ) != 'RS256' :
303
324
error_message = (
304
325
'Firebase {0} has incorrect algorithm. Expected "RS256" but got '
305
326
'"{1}". {2}' .format (self .short_name , header .get ('alg' ), verify_id_token_msg ))
@@ -330,11 +351,14 @@ def verify(self, token, request):
330
351
raise self ._invalid_token_error (error_message )
331
352
332
353
try :
333
- verified_claims = google .oauth2 .id_token .verify_token (
334
- token ,
335
- request = request ,
336
- audience = self .project_id ,
337
- certs_url = self .cert_url )
354
+ if emulated :
355
+ verified_claims = payload
356
+ else :
357
+ verified_claims = google .oauth2 .id_token .verify_token (
358
+ token ,
359
+ request = request ,
360
+ audience = self .project_id ,
361
+ certs_url = self .cert_url )
338
362
verified_claims ['uid' ] = verified_claims ['sub' ]
339
363
return verified_claims
340
364
except google .auth .exceptions .TransportError as error :
0 commit comments