skip to Main Content

When using the new .NavigateToLogin in a Blazor app in .NET 7 as recommended here, how do I pass a domain hint when calling NavigateToLogin (or NavigateToLogout)? Or is there a way via setup to make the domain hint be added automatically?

Without the domain hint, my users now have an extra step for both log in and out. (I am using MSAL for Open ID Connect with Azure AD.)

From this page, it appears as though I can new-up a InteractiveRequestOptions object, run options.TryAddAdditionalParameter("domain_hint", "mydomain.com");, and pass that into Navigation.NavigateToLogin–but it doesn’t work at all; it is simply ineffective.

2

Answers


  1. Chosen as BEST ANSWER

    From this page, I founds that I can create a InteractiveRequestOptions object, run options.TryAddAdditionalParameter("domainHint", "mydomain.com");, and pass that into Navigation.NavigateToLogin, and it works great. Just be careful to use domainHint and not domain_hint, contrary to several pieces of documentation.


  2. I think this issue is still applicable: https://github.com/dotnet/aspnetcore/issues/40046#issuecomment-1042575825 – at least that’s how I solved it. Not sure if there’s a better way to do this.

    So, step 1: You add class AuthExtensions:

    using System.Text.Json.Serialization;
    using Microsoft.AspNetCore.Components;
    using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
    using Microsoft.Extensions.DependencyInjection.Extensions;
    using Microsoft.Extensions.Options;
    
    namespace Your.Namespace;
    /// <summary>
    /// https://github.com/dotnet/aspnetcore/issues/40046
    /// </summary>
    public static class AuthExtensions
    {
        /// <summary>
        /// Adds support for Auth0 authentication for SPA applications using <see cref="Auth0OidcProviderOptions"/> and the <see cref="RemoteAuthenticationState"/>.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
        /// <param name="configure">An action that will configure the <see cref="RemoteAuthenticationOptions{TProviderOptions}"/>.</param>
        /// <returns>The <see cref="IServiceCollection"/> where the services were registered.</returns>
        public static IRemoteAuthenticationBuilder<RemoteAuthenticationState, RemoteUserAccount> AddAuth0OidcAuthentication(this IServiceCollection services, Action<RemoteAuthenticationOptions<Auth0OidcProviderOptions>> configure)
        {
            services.TryAddEnumerable(ServiceDescriptor.Scoped<IPostConfigureOptions<RemoteAuthenticationOptions<Auth0OidcProviderOptions>>, DefaultAuth0OidcOptionsConfiguration>());
            return services.AddRemoteAuthentication<RemoteAuthenticationState, RemoteUserAccount, Auth0OidcProviderOptions>(configure);
        }
    }
    
    public class Auth0OidcProviderOptions : OidcProviderOptions
    {
        public MetadataSeed MetadataSeed { get; set; } = new();
    }
    
    public class MetadataSeed
    {
        [JsonPropertyName("end_session_endpoint")]
        public string EndSessionEndpoint { get; set; } = null!;
    }
    
    // Copy/paste from Microsoft.AspNetCore.Components.WebAssembly.Authentication with the option type changed.
    public class DefaultAuth0OidcOptionsConfiguration : IPostConfigureOptions<RemoteAuthenticationOptions<Auth0OidcProviderOptions>>
    {
        private readonly NavigationManager _navigationManager;
    
        public DefaultAuth0OidcOptionsConfiguration(NavigationManager navigationManager) => _navigationManager = navigationManager;
    
        public void Configure(RemoteAuthenticationOptions<Auth0OidcProviderOptions> options)
        {
            if (options == null)
            {
                return;
            }
    
            options.UserOptions.AuthenticationType ??= options.ProviderOptions.ClientId;
    
            var redirectUri = options.ProviderOptions.RedirectUri;
            if (redirectUri == null || !Uri.TryCreate(redirectUri, UriKind.Absolute, out _))
            {
                redirectUri ??= "authentication/login-callback";
                options.ProviderOptions.RedirectUri = _navigationManager.ToAbsoluteUri(redirectUri).AbsoluteUri;
            }
    
            var logoutUri = options.ProviderOptions.PostLogoutRedirectUri;
            if (logoutUri == null || !Uri.TryCreate(logoutUri, UriKind.Absolute, out _))
            {
                logoutUri ??= "authentication/logout-callback";
                options.ProviderOptions.PostLogoutRedirectUri = _navigationManager.ToAbsoluteUri(logoutUri).AbsoluteUri;
            }
        }
    
        public void PostConfigure(string name, RemoteAuthenticationOptions<Auth0OidcProviderOptions> options)
        {
            if (string.Equals(name, Options.DefaultName, StringComparison.Ordinal))
            {
                Configure(options);
            }
        }
    }
    

    Then in your program.cs you wire it up like this:

    builder.Services.AddAuth0OidcAuthentication(options =>
    {
        var authority = builder.Configuration["GoogleAuth:Authority"];
        var clientId = builder.Configuration["GoogleAuth:ClientId"];
        options.ProviderOptions.MetadataSeed.EndSessionEndpoint = $"{authority}/v2/logout?client_id={clientId}&returnTo={builder.HostEnvironment.BaseAddress}";
    
        // Allowing only MyDomain.Com users
        options.ProviderOptions.AdditionalProviderParameters.Add("hd", builder.Configuration["GoogleAuth:hd"]);
    });
    

    Note that I’m not 100% sure which exact parameter you should be adding.
    "hd" is the domain hint parameter for google cloud based domains: https://developers.google.com/identity/openid-connect/openid-connect#hd-param

    Based on this guide: https://learn.microsoft.com/en-us/azure/active-directory-b2c/direct-signin?pivots=b2c-user-flow – It looks like the Azure domain hint parameter is either login_hint or domain_hint

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search