Base solution for your next web application
Open Closed

Google SSO using multiple subdomains #9734


User avatar
1
wydeedev created
  • Product version: 9.1.0
  • Product type: MVC
  • Product framework type: .NET Core

Hello all!

I'm trying to use Google SSO in order to make users login in my application.

I go to https://console.developers.google.com/ , get the ClientId and the ClientSecret and place them in the appsettings.json of the application.

It is a multi-tenant application, so each tenant will have its own subdomain. For instance, client.mydomain.com and client2.mydomain.com.

Since Google does not support wildcards in order to match all the subdomains, how can I achieve a behavior where, regardless of the subdomain used, Google SSO works?

I get this error, if I try to achieve a subdomain that is not in the list of authorized URIs: Erro 400: redirecturimismatch The redirect URI in the request, https://client2.mydomain.com/signin-google, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/${yourclientid}?project=${yourprojectnumber}

Of course, if I put all my subdomains in Google in the authorized URIs it will work, but it is not a good practice to do that everytime a new tenant is added.

How can achieve the behavior?


5 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @wydeedev

    Did you set the returl URL on Google to https://mydomain.com/signin-google and try this way ? I'm not %100 sure but I remember something like this worked for me.

  • User Avatar
    0
    wydeedev created

    Hi @ismcagdas, thanks for your answer.

    I've tried but with no success, it returns the same error as before.

    Do you have any workaround for this or how do you manage these kind of issues? Do you enter all the subdomains in order to authorize them? This does not sound like a good solution in the long run.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @wydeedev

    Actually, I haven't tried Google SSO with subdomains. You can follow such an approach;

    You can use main website url for Google SSO with a tenantId query string parameter, using state parameter of Google SSO as explained here https://stackoverflow.com/a/13769166/6681451.

    Then, you can write a custom tenant resolver which is similar to https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.AspNetCore/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs. This resolver should resolve tenantId from Google SSO's state paraemter.

    Then, user should be logged in correctly but in the main URL. So you also need to redirect user to related subdomain after a successfull login.

  • User Avatar
    0
    kfrancis created

    Hmm, what does this look like actually? Same problem, different oauth provider (of my own writing):

    I do know that I'll have to do something here to Request.Host to stop grabbing the subdomain since the provider only passes the callback path.

    https://github.com/Clinical-Support-Systems/oneid-oauth-middleware/blob/9ece0e71be0a70371f9d0de78ae8144ec00f502e/src/AspNet.Security.OAuth.OneID/OneIdAuthenticationHandler.cs#L398

    Perhaps something like this:

    Uri request = new Uri("http://subdomain.domain.co.uk");
    string host = request.Host;
    string hostWithoutPrefix = null;
    
    var tlds = new List<string>()
    {
        //the second- and third-level TLDs you expect go here, set to null if working with single-level TLDs only
        "co.uk"
    };
    
    if (tlds != null)
    {
        foreach (var tld in tlds)
        {
            Regex regex = new Regex($"(?<=\\.|)\\w+\\.{tld}$");
            Match match = regex.Match(host);
    
    
            if (match.Success)
                hostWithoutPrefix = match.Groups[0].Value;
        }
    }
    
    //second/third levels not provided or not found -- try single-level
    if (string.IsNullOrWhiteSpace(hostWithoutPrefix))
    {
        Regex regex = new Regex("(?<=\\.|)\\w+\\.\\w+$");
        Match match = regex.Match(host);
    
    
        if (match.Success)
            hostWithoutPrefix = match.Groups[0].Value;
    }
    

    But, do you know of a code example of including this in the query string and/or state so that I can redirect back to the right tenancy (with subdomain)?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @kfrancis

    Sorry, I couldn't understand your question. Do you mean implementing this on your library or on the client app which uses your library ?