From 44e8e7aab71535ca0ec266f7b4c85775f467480a Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Fri, 28 Jan 2022 14:09:24 -0500 Subject: [PATCH] Adding Firebase Documentation (#911) Add reference documentation for security-firebase module. Mentioning Firebase starter and sample in getting-started and sagan-index. Edits in sample readme and Javadoc format for better readability. Fix a typo in sample. --- docs/src/main/asciidoc/getting-started.adoc | 7 ++ docs/src/main/asciidoc/sagan-index.adoc | 11 +++- docs/src/main/asciidoc/security-firebase.adoc | 64 +++++++++++++++++++ .../README.adoc | 2 +- .../src/main/resources/static/index.html | 2 +- .../firebase/FirebaseJwtTokenDecoder.java | 14 ++-- .../firebase/FirebaseTokenValidator.java | 8 ++- 7 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 docs/src/main/asciidoc/security-firebase.adoc diff --git a/docs/src/main/asciidoc/getting-started.adoc b/docs/src/main/asciidoc/getting-started.adoc index afd6d9ee9a..eebeeffadc 100644 --- a/docs/src/main/asciidoc/getting-started.adoc +++ b/docs/src/main/asciidoc/getting-started.adoc @@ -121,6 +121,10 @@ A summary of these artifacts are provided below. | Provides a security layer over applications deployed to Google Cloud | <> +| Security - Firebase +| Provides a security layer over applications deployed to Firebase +| <> + |=== ==== Spring Initializr @@ -176,6 +180,9 @@ https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-g | Cloud Security - IAP | https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-security-iap-sample[spring-cloud-gcp-security-iap-sample] + +| Cloud Security - Firebase +| https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample[spring-cloud-gcp-security-firebase-sample] |=== Each sample application demonstrates how to use Spring Cloud GCP libraries in context and how to setup the dependencies for the project. diff --git a/docs/src/main/asciidoc/sagan-index.adoc b/docs/src/main/asciidoc/sagan-index.adoc index a7dad0db99..8564267fae 100644 --- a/docs/src/main/asciidoc/sagan-index.adoc +++ b/docs/src/main/asciidoc/sagan-index.adoc @@ -15,6 +15,7 @@ Project features include: * Google Cloud Storage (Spring Resource and Spring Integration) * Google Cloud Vision API Template * Spring Security identity extraction from Google Cloud IAP headers. +* Spring Security identity extraction from Firebase Authentication headers. * Google Cloud BigQuery with Spring Integration == Getting Started @@ -95,6 +96,10 @@ A sample of these artifacts are provided below. | Extracts IAP identity information from applications deployed to Google Cloud | `com.google.cloud:spring-cloud-gcp-starter-security-iap` +| Security - Firebase +| Extracts IAP identity information from applications deployed to Firebase +| `com.google.cloud:spring-cloud-gcp-starter-security-firebase` + |=== == Code Samples @@ -111,7 +116,8 @@ The table below highlights several samples of the most commonly used integration | Cloud Spanner | https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-data-spanner-repository-sample[spring-cloud-gcp-data-spanner-repository-sample] -| https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-data-spanner-template-sample[spring-cloud-gcp-data-spanner-template-sample] + + https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-data-spanner-template-sample[spring-cloud-gcp-data-spanner-template-sample] | Cloud Datastore | https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-data-datastore-sample[spring-cloud-gcp-data-datastore-sample] @@ -136,6 +142,9 @@ The table below highlights several samples of the most commonly used integration | Cloud Security - IAP | https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-security-iap-sample[spring-cloud-gcp-security-iap-sample] + +| Cloud Security - Firebase +| https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample[spring-cloud-gcp-security-firebase-sample] |=== == Initializr diff --git a/docs/src/main/asciidoc/security-firebase.adoc b/docs/src/main/asciidoc/security-firebase.adoc new file mode 100644 index 0000000000..b24d4131f6 --- /dev/null +++ b/docs/src/main/asciidoc/security-firebase.adoc @@ -0,0 +1,64 @@ +:spring-security-ref: https://docs.spring.io/spring-security/reference/ +:spring-security-javadoc: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/ + +[#security-firebase] +== Firebase Authentication + +https://firebase.google.com/products/auth[Firebase Authentication] provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your link:https://firebase.google.com/[Firebase] app. + +The Security Firebase starter uses {spring-security-ref}servlet/oauth2/resource-server/index.html[Spring Security OAuth 2.0 Resource Server] functionality to extract user identity from OAuth2 Authorization header. + +The Firebase JWT tokens are validated with rules presented link:https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library[here]. The following claims are validated automatically: + +* Expiration time: Must be in the future +* Issued-at time : Must be in the past +* Audience : Must be the firebase project id +* Issuer: Must be "https://securetoken.google.com/`` " +* Authentication time : Must be in the past +* Subject : Must not be empty + +NOTE: If you create a custom {spring-security-javadoc}config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[`WebSecurityConfigurerAdapter`], enable extracting user identity by adding `.oauth2ResourceServer().jwt()` configuration to the {spring-security-javadoc}config/annotation/web/builders/HttpSecurity.html[`HttpSecurity`] object. +If no custom {spring-security-javadoc}config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[`WebSecurityConfigurerAdapter`] is present, nothing needs to be done because Spring Boot will add this customization by default. + +Starter Maven coordinates, using <>: + +[source,xml] +---- + + com.google.cloud + spring-cloud-gcp-starter-security-firebase + +---- + +Starter Gradle coordinates: + +[source] +---- +dependencies { + implementation("com.google.cloud:spring-cloud-gcp-starter-security-firebase") +} +---- + +=== Configuration +The following properties are available. + +CAUTION: Modifying public-keys-endpoint property might be useful for testing, but the defaults should not be changed in production. + +|==================================================== +|Name |Description |Required |Default + +|`spring.cloud.gcp.security.firebase.project-id` +|Overrides the GCP project ID specified in the Core module. +|false +| + +|`spring.cloud.gcp.security.firebase.public-keys-endpoint` +|Link to Google's public endpoint containing Firebase public keys. +|true +|`https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com` + +|==================================================== + +=== Sample + +A link:https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample[sample application] is available. This sample app provides simple login page using link:https://github.com/firebase/firebaseui-web[firebase-ui] to fetch the JWT token. \ No newline at end of file diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/README.adoc b/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/README.adoc index c84a550368..4c913ce893 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/README.adoc +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/README.adoc @@ -10,7 +10,7 @@ This sample app provides simple login page using https://github.com/firebase/fir image:http://gstatic.com/cloudssh/images/open-btn.svg[link=https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fspring-cloud-gcp&cloudshell_open_in_editor=spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/README.adoc] -1. Create a new firebase project as instructed https://firebase.google.com/docs/web/setup[here] +1. Create a new firebase project as instructed https://firebase.google.com/docs/web/setup#create-firebase-project-and-app[here]. You need to finish "Create a Firebase project" and "Register your app" in Step 1. 2. Once you finish the process make sure you configure the following environment variables before running the app: a. FIREBASE_CONFIG_API_KEY: Should be your "apiKey" value (you can find it in Firebase console project settings in "Web API Key" field) b. FIREBASE_CONFIG_APP_ID: Should be your "appId" value for the application you set up in step 1. diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/src/main/resources/static/index.html b/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/src/main/resources/static/index.html index 0d8f476488..21d825e96d 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/src/main/resources/static/index.html +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-security-firebase-sample/src/main/resources/static/index.html @@ -40,7 +40,7 @@ $("#logoutBtn").click(function () { firebase.auth().signOut().then(function () { firebaseUser = null; - $("#loginBtn").css("visibiliy", "visible"); + $("#loginBtn").css("visibility", "visible"); $("#logoutBtn").css("visibility", "hidden"); }); }); diff --git a/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseJwtTokenDecoder.java b/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseJwtTokenDecoder.java index c535368ffb..27588fca14 100644 --- a/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseJwtTokenDecoder.java +++ b/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseJwtTokenDecoder.java @@ -49,11 +49,15 @@ * keys are cached locally and only refreshed when the expiration time is past. Besides using the * RSA keys to validate the token signature, this decoder also uses a pre=configured {@link * org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator} to validate all the - * claims. The following validators are used by this class: {@link - * org.springframework.security.oauth2.jwt.JwtTimestampValidator} - Validates the expiration date of - * the Token {@link org.springframework.security.oauth2.jwt.JwtIssuerValidator} - Validates the iss - * claim header {@link FirebaseTokenValidator} - Validates all other headers according to definition - * at https://firebase.google.com/docs/auth/admin/verify-id-tokens + * claims. The following validators are used by this class: + *
    + *
  • {@link org.springframework.security.oauth2.jwt.JwtTimestampValidator} - Validates the + * expiration date of the Token
  • + *
  • {@link org.springframework.security.oauth2.jwt.JwtIssuerValidator} - Validates the iss + * claim header
  • + *
  • {@link FirebaseTokenValidator} - Validates all other headers according to definition at + * https://firebase.google.com/docs/auth/admin/verify-id-tokens
  • + *
* * @since 1.2.2 */ diff --git a/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseTokenValidator.java b/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseTokenValidator.java index c55fac11dd..d0a0d15718 100644 --- a/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseTokenValidator.java +++ b/spring-cloud-gcp-security-firebase/src/main/java/com/google/cloud/spring/security/firebase/FirebaseTokenValidator.java @@ -35,8 +35,12 @@ * *

This validator will check the following claims: * - *

- iat : Must be in the past - aud : Must be the firebase project id - auth_time : Must be in - * the past - sub : Must not be empty + *

    + *
  • iat : Must be in the past
  • + *
  • aud : Must be the firebase project id
  • + *
  • auth_time : Must be in the past
  • + *
  • sub : Must not be empty
  • + *
* * @since 1.2.2 */