0

What I am trying to do

I am trying to implement Google OpenID Connect as a means to login to an ASP.NET Core 3.1 website using Google's instructions:

https://developers.google.com/identity/protocols/oauth2/openid-connect#server-flow

Under step 2 of the server flow (Send an authentication request to Google) they recommend retrieving information from their OpenID Discovery Document:

You should retrieve the base URI from the Discovery document using the authorization_endpoint metadata value.

I am currently trying to dynamically deserialize the JSON to a Dictionary<string, string> by using Newtonsoft.Json. But it is giving me some issues (can't seem to deserialize a JSON string array) and I am considering changing my strategy to creating a model for the Discovery Document and using System.Text.Json to deserialize.

Now my question is

How sensitive is Google's Discovery Document to changes that would lead to me having to update my DiscoveryDocument.cs model?

Dilemma

With the Newtonsoft.Json way everything will still work, even if Google decides to remove a random key.

But using the System.Text.Json is the easy way out for me now and removes a dependency on the Newtonsoft library, though I may run into trouble later if Google's Discovery Document changes.

Caedendi
  • 37
  • 6

1 Answers1

1

I think you will have a much easier time to use the Microsoft.IdentityModel.Protocols and Microsoft.IdentityModel.Protocols.OpenIdConnect NuGet packages and use the included parser to do it all for you. The items in the document is pretty standardized but not every provider provides all the items.

public class OpenIDSettings : IOpenIDSettings
{
    public string Issuer { get; }
    public string jwks_uri { get; }
    public string authorization_endpoint { get; }
    public string token_endpoint { get; }
    public string userinfo_endpoint { get; }
    public string end_session_endpoint { get; }
    public string check_session_iframe { get; }
    public string revocation_endpoint { get; }
    public string introspection_endpoint { get; }
    public string device_authorization_endpoint { get; }

    public ICollection<string> scopes_supported { get; }
    public ICollection<string> claims_supported { get; }

    public OpenIDSettings(string endpoint)
    {
        var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            $"{endpoint}/.well-known/openid-configuration",
            new OpenIdConnectConfigurationRetriever());

        //If you get an exception here, then provider is not running or reachable
        var document = configurationManager.GetConfigurationAsync().Result;

        //Add the necessary code to populate the properties in this class
        Issuer = document.Issuer;
        jwks_uri = document.JwksUri;
        authorization_endpoint = document.AuthorizationEndpoint;
        token_endpoint = document.TokenEndpoint;
        userinfo_endpoint = document.UserInfoEndpoint;
        end_session_endpoint = document.EndSessionEndpoint;
        check_session_iframe = document.CheckSessionIframe;

        scopes_supported = document.ScopesSupported;
        claims_supported = document.ClaimsSupported;

        if (document.AdditionalData.ContainsKey("revocation_endpoint"))
            revocation_endpoint = (string)(document.AdditionalData["revocation_endpoint"]);
        
        if (document.AdditionalData.ContainsKey("introspection_endpoint"))
            introspection_endpoint = (string)(document.AdditionalData["introspection_endpoint"]);

        if (document.AdditionalData.ContainsKey("device_authorization_endpoint"))
            device_authorization_endpoint = (string)(document.AdditionalData["device_authorization_endpoint"]);
    }
}
Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
  • If I understand this correctly, you are advising me to use a NuGet package for Azure Active Directory and use the included parser? I do not want a dependency on Azure Active Directory if I don't use it. Isn't there a more universal package for OpenID Connect you can recommend? – Caedendi Aug 31 '20 at 12:23
  • As an alternative you can try https://github.com/IdentityModel/IdentityModel , a client helper library to do the validation.Source code at https://github.com/IdentityModel/IdentityModel hope that makes an acceptable answer. – Tore Nestenius Aug 31 '20 at 12:46