oidc-token-manager library with Google Identity Platform - Part 2
This post is a continuation of the previous one previous one where I started to describe my attempt to use library oidc-token-manager with Google Identity Platform.
I was stuck at the moment when this library couldn’t validate a signature for an access token because of the unexpected format of the certs. I found in the documentation that I can provide certs for this library myself in the config and the library wouldn’t make a request for them.
I did this in the config property by specifying the value for the jwks property. After this, config in index.html looked like:
var config = {
authority: "https://accounts.google.com",
client_id: "342665198077-tp56a5pab4ei5lri37nkba69b6sqghou.apps.googleusercontent.com",
redirect_uri: window.location.protocol + "//" + window.location.host + "/callback.html",
post_logout_redirect_uri: window.location.protocol + "//" + window.location.host + "/index.html",
response_type: "id_token token",
scope: "email",
silent_redirect_uri: window.location.protocol + "//" + window.location.host + "/frame.html",
popup_redirect_uri: window.location.protocol + "//" + window.location.host + "/popup.html",
jwks: {
keys: [{
kty: "RSA",
x5c: ["-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIUQ9p7LoIOI8wD …[removded for brevity ]... eTh45xGznVwh8\n-----END CERTIFICATE-----\n"]
}]
},
silent_renew: true
};
and in the callback.html, config looked like this:
var config = {
authority: "https://accounts.google.com",
client_id: "342665198077-tp56a5pab4ei5lri37nkba69b6sqghou.apps.googleusercontent.com",
jwks: {
keys: [{
kty: "RSA",
x5c: ["-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIUQ9p7LoIOI8wD …[removded for brevity ]... eTh45xGznVwh8\n-----END CERTIFICATE-----\n"]
}]
},
};
I found a value for this x5c property requesting this url https://www.googleapis.com/oauth2/v1/certs and this url I found in the file downloaded from Google Developer Console, which I used in the previous post to get the client_id. You can read here how I got it. (link). Hardcoding the value for x5c is a very bad solution because Google often changes certs but for testing it’s sufficient for me.
After this, when I opened the application I got this screen: [networkError.png]
And the web browser console showed me this:
This error came from a request for userinfo. Fortunately, I don’t need to get a user profile. All I need to know about the user is their email and it is in the token. So I can turn off loading the user profile with this option:
load_user_profile : false,
With this option set to false, the oidc-token-manager library won’t send requests to Google for a user profile. After this, another attempt to get a token resulted in the following message in the browser console:
I could see my token was also in the local storage of the browser:
As you can see, I got a token from Google Identity Provider and I could use it to get access to the API but my solution is far from perfect.
I made a dangerous assumption in the configuration of oidc-token-manager. While fetching certs from this url https://www.googleapis.com/oauth2/v1/certs, I got a response like this:
{
"8087d258ac19c0fcf1dab7a908c221cdd81d5512": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIBzgwCmlF7SMwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY … [removed for brevity]... ]eOV9CqsTSJCZ9baLqF4wk6botNe187A88wnj5OVbyoVZK4SMW\n-----END CERTIFICATE-----\n",
"428489e3a6753680152ffcf1a8f7d0379f28ce9e": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIUQ9p7LoIOI8wDQYJKoZIhvcNAQEFB …[removed for brevity]... xcOKB6l8wBqKDmyc1aMXZ+H0WkBgvcEHqeTh45xGznVwh8\n-----END CERTIFICATE-----\n"
}
And I assumed that the second cert was the right one to validate the token. I chose the second one because the first one didn’t work. Instead of this, I should have made a choice dependent on the value provided in the token header which looked like this:
{"alg":"RS256","kid":"428489e3a6753680152ffcf1a8f7d0379f28ce9e"}
The property kid indicates that in the object with certs, I should use the one with the property like the kid value. I discovered that this was the second property but it won’t always be true. I should choose a certificate dynamically but I didn’t want to change source code of the library oidc-token-manager, so that’s why I hardcoded it.
An authentication is a non-trivial challenge for any app. Many developers have tools and techniques they trust for building traditional (page-by-page) auth flows. I thought for a while about building a traditional membership system but I finally decided to try something different. We’ll see the consequences of my choices in the future. For now, I have proven that I can obtain access tokens from Google using the library oidc-token-manager, but the implementation isn’t perfect. If I want to use this library, I would have to change it a bit. I don’t want to do this until I check other possibilities. Future posts will be about the further exploration of the web client authentication with Google Identity Provider.
Related posts:
- Enrolling in "Daj się poznać"
- "Daj się poznać" - Project details"
- I'm holding a Project Rider EAP
- Installing ASP .NET Core 1 on Ubuntu 14.04
- My first ASP NET Core 1.0 web application
- Project setup - server-side
- Project setup - client-side
- Adding styling to my application
- Angular 2 Confirm Dialog Component
- Before going into production
- Publishing to Azure
- Setting up the Web client for Google Identity Platform
- oidc-token-manager library with Google Identity Platform - Part 1
- oidc-token-manager library with Google Identity Platform - Part 2
- Accessing API with token from Google Identity Provider
- How portable is ASP .NET Core 1.0?
- When dotPeek can save your live
- Reading code as if it were a book
- ASP .NET Core Configuration
- Getting started with IdentityServer4
- IdentityServer4 - accessing API
- Dealing with secrets in ASP .NET Core
- Google Identity Provider with IdentityServer4
- Upgrading to Angular2 RC1
- Experimenting with Angular2 CLI
- Migrating to ASP .NET Core RC2
- Epilogue: Daj się poznać series
Comments
comments powered by Disqus