Skip to content

Commit 1f72249

Browse files
authored
Proper handling of exceptions when verifying ID tokens (#64)
* Proper handling of exceptions when verifying ID tokens * Removing some redundant test assertions
1 parent 178c54f commit 1f72249

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/main/java/com/google/firebase/auth/internal/FirebaseTokenVerifier.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public final class FirebaseTokenVerifier extends IdTokenVerifier {
5858
private static final String ISSUER_PREFIX = "https://securetoken.google.com/";
5959
private static final String FIREBASE_AUDIENCE =
6060
"https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit";
61-
private static final String ERROR_CODE = "ERROR_INVALID_CREDENTIAL";
61+
private static final String ERROR_INVALID_CREDENTIAL = "ERROR_INVALID_CREDENTIAL";
62+
private static final String ERROR_RUNTIME_EXCEPTION = "ERROR_RUNTIME_EXCEPTION";
6263
private static final String PROJECT_ID_MATCH_MESSAGE =
6364
" Make sure the ID token comes from the same Firebase project as the service account used to "
6465
+ "authenticate this SDK.";
@@ -138,18 +139,18 @@ public boolean verifyTokenAndSignature(IdToken token) throws FirebaseAuthExcepti
138139

139140
if (errorMessage != null) {
140141
errorMessage += VERIFY_ID_TOKEN_DOCS_MESSAGE;
141-
throw new FirebaseAuthException(ERROR_CODE, errorMessage);
142+
throw new FirebaseAuthException(ERROR_INVALID_CREDENTIAL, errorMessage);
142143
}
143144

144145
try {
145146
if (!verifySignature(token)) {
146147
throw new FirebaseAuthException(
147-
ERROR_CODE,
148+
ERROR_INVALID_CREDENTIAL,
148149
"Firebase ID token isn't signed by a valid public key." + VERIFY_ID_TOKEN_DOCS_MESSAGE);
149150
}
150151
} catch (IOException | GeneralSecurityException e) {
151152
throw new FirebaseAuthException(
152-
ERROR_CODE, "Firebase ID token has invalid signature." + VERIFY_ID_TOKEN_DOCS_MESSAGE);
153+
ERROR_RUNTIME_EXCEPTION, "Error while verifying token signature.", e);
153154
}
154155

155156
return true;

src/test/java/com/google/firebase/auth/internal/FirebaseTokenVerifierTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.google.api.client.auth.openidconnect.IdToken;
2323
import com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager;
24+
import com.google.api.client.http.LowLevelHttpRequest;
2425
import com.google.api.client.json.JsonFactory;
2526
import com.google.api.client.json.gson.GsonFactory;
2627
import com.google.api.client.json.webtoken.JsonWebSignature;
@@ -31,6 +32,7 @@
3132
import com.google.api.client.testing.http.MockHttpTransport;
3233
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
3334
import com.google.common.io.BaseEncoding;
35+
import com.google.firebase.auth.FirebaseAuthException;
3436
import com.google.firebase.auth.FirebaseToken;
3537
import com.google.firebase.auth.TestOnlyImplFirebaseAuthTrampolines;
3638
import com.google.firebase.testing.ServiceAccount;
@@ -42,6 +44,7 @@
4244
import java.security.spec.InvalidKeySpecException;
4345
import java.security.spec.KeySpec;
4446
import java.security.spec.PKCS8EncodedKeySpec;
47+
import org.junit.Assert;
4548
import org.junit.Before;
4649
import org.junit.Rule;
4750
import org.junit.Test;
@@ -265,6 +268,36 @@ public void verifyTokenFailure_WrongCert() throws Exception {
265268
verifier.verifyTokenAndSignature(TestOnlyImplFirebaseAuthTrampolines.getToken(token));
266269
}
267270

271+
@Test
272+
public void verifyTokenCertificateError() throws Exception {
273+
FirebaseToken token =
274+
TestOnlyImplFirebaseAuthTrampolines.parseToken(
275+
FACTORY, createToken(createHeader(), createPayload()));
276+
277+
MockHttpTransport mockTransport = new MockHttpTransport() {
278+
@Override
279+
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
280+
throw new IOException("Expected error");
281+
}
282+
};
283+
FirebaseTokenVerifier verifier = new FirebaseTokenVerifier.Builder()
284+
.setClock(CLOCK)
285+
.setPublicKeysManager(
286+
new GooglePublicKeysManager.Builder(mockTransport, FACTORY)
287+
.setClock(CLOCK)
288+
.setPublicCertsEncodedUrl(FirebaseTokenVerifier.CLIENT_CERT_URL)
289+
.build())
290+
.setProjectId(PROJECT_ID)
291+
.build();
292+
try {
293+
verifier.verifyTokenAndSignature(TestOnlyImplFirebaseAuthTrampolines.getToken(token));
294+
Assert.fail("No exception thrown");
295+
} catch (FirebaseAuthException expected) {
296+
assertTrue(expected.getCause() instanceof IOException);
297+
assertEquals("Expected error", expected.getCause().getMessage());
298+
}
299+
}
300+
268301
@Test
269302
public void legacyCustomToken() throws Exception {
270303
initCrypto(ServiceAccount.OWNER.getPrivateKey(), ServiceAccount.NONE.getCert());

0 commit comments

Comments
 (0)