Google Authentication

This guide will show you how to configure Weavy to use Google as an identity provider.

Prerequisites

To continue this guide you should first follow Getting Started guide for the server SDK . It can also be helpful to read our article about OpenID Connect (which Google authentication is based on).

You will also need to install the Microsoft.Owin.Security.OpenIdConnect Nuget package (if you don't have it already).

Configuration

The following settings are required for Weavy to use Google authentication.

Web server

The Weavy website in IIS must be configured with the following settings:

Anonymous Authentication = Enabled
Forms Authentication = Disabled
Windows Authentication = Disabled

Web.config

The web.config file should have the following configuration:

<system.web>
    <authentication mode="None" />
</system.web>

Startup Configuration

First step in configuring the Google OpenID provider is registering your application in the Google API Console. See Google Identity Platform for detailed instructions.

When asked to enter an authorized redirect URI you should enter the url to your weavy instance followed by /sign-in-callback, .i.e. https://{weavyurl}/sign-in-callback.

Once you have the ClientId and ClientSecret you should add them to your web.config.

<appSettings>
    <!-- the application id for the app you registered -->
    <add key="GoogleClientId" value="..." />
     <!-- the client secret for the app you registered -->
    <add key="GoogleClientSecret" value="..." />
    <!-- the domain for your organization, e.g. example.com -->
    <add key="GoogleDomain" value="..." /> 
</appSettings>

Next you need to add the following code to the Startup.cs file located in the App_Start folder:

public partial class Startup {

    public void Configuration(IAppBuilder app) {
        app.UseWeavy();

        var googleClientId = ConfigurationManager.AppSettings["GoogleClientID"];
        var googleClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"];
        var googleDomain = ConfigurationManager.AppSettings["GoogleDomain"];
        if (googleClientId != null && googleClientSecret != null && googleDomain != null) {
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
                AuthenticationType = "Google",
                AuthenticationMode = AuthenticationMode.Passive,
                Authority = "https://accounts.google.com",
                Caption = "Google",
                ClientId = googleClientId,
                ClientSecret = googleClientSecret,
                Notifications = new OpenIdConnectAuthenticationNotifications() {
                    RedirectToIdentityProvider = (context) => {
                        // this ensures that the address used for sign in and sign out is picked up dynamically (it must still be registered in the Google developer console)
                        context.ProtocolMessage.RedirectUri = WeavyContext.Current.ApplicationUrl + "signin-google";

                        // set the hd parameter to optimize the OpenID Connect flow for users of the specified domain.  
                        context.ProtocolMessage.Parameters.Add("hd", googleDomain);

                        return Task.CompletedTask;
                    },
                    SecurityTokenValidated = (context) => {
                        // validate domain
                        string hd = context.AuthenticationTicket.Identity.FindFirst("hd")?.Value;
                        if (hd == null) {
                            throw new SecurityTokenValidationException("No hosted domain (hd) found in claims.");
                        } else if (!hd.Equals(googleDomain, StringComparison.OrdinalIgnoreCase)) {
                            throw new SecurityTokenValidationException($"Hosted domain {hd} is not allowed.");
                        }

                        // add authentication_type claim
                        context.AuthenticationTicket.Identity.AddClaim(new Claim("authentication_type", context.Options.AuthenticationType, null, LoginService.LOCAL_AUTHENTICATION_TYPE));
                        return Task.CompletedTask;
                    },
                    AuthenticationFailed = (context) => {
                        context.OwinContext.Response.Redirect(WeavyContext.Current.ApplicationPath + "error/unauthorized");
                        context.HandleResponse();
                        return Task.CompletedTask;
                    }
                },
                Scope = "openid email profile",
            });
        }
    }
}

And that's it, Weavy will now display a button on the sign in page allowing your users to authenticate against your Google Apps user directory.