David Shochet
David Shochet

Reputation: 5375

How can I pass id_token_hint

I have a blazor application. It is authenticated using Azure AD B2C. The sign in user flow is set to Require ID Token in logout requests. When the user is trying to log out, the following error is received:

Sorry, but we're having trouble signing you in. ... The id_token_hint parameter has not been specified in the request. Please provide token and try again.

I know that I need to pass id_token_hint as a query parameter, but can't find how exactly this can be done.

Upvotes: 0

Views: 1124

Answers (2)

Paul Suart
Paul Suart

Reputation: 6713

This works in dotnet 7 Blazor WASM:

    var idToken = await IdTokenHelper.GetIdTokenAsync();
    var options = new InteractiveRequestOptions
    {
        Interaction = InteractionType.SignOut,
        ReturnUrl = null
    };

    // Casing of "idTokenHint" here is correct.  Msal.js converts to "id_token_hint" 🤯
    options.TryAddAdditionalParameter("idTokenHint", idToken);

    // This is equivalent to the "ToState" extension method which is internal.
    var serializedOptions = JsonSerializer.Serialize(options, new JsonSerializerOptions
    {
        MaxDepth = 32,
        PropertyNameCaseInsensitive = true,
    });

    Navigation.NavigateTo("authentication/logout", new NavigationOptions { HistoryEntryState = serializedOptions});

Implementation of GetIdTokenAsync is:

private readonly ILocalStorageService _localStorageService;

public IdTokenHelper(ILocalStorageService localStorageService)
{
    _localStorageService = localStorageService;
}

public async Task<string?> GetIdTokenAsync()
{
    foreach (var key in await _localStorageService.KeysAsync())
    {
        try
        {
            var item = await _localStorageService.GetItemAsync<TokenContainer>(key);
            if (item.CredentialType == "IdToken")
                return item.Secret;
        }
        catch
        {
            // Swallow entries that aren't serializable into the TokenContainer DTO
        }
    }

    return null;
}

// ReSharper disable once ClassNeverInstantiated.Local
private record TokenContainer(
    [property: JsonPropertyName("credentialType")] string CredentialType,
    [property: JsonPropertyName("secret")] string Secret);

Note this uses the Blazored Localstorage nuget package.

Upvotes: 0

Paul Guz
Paul Guz

Reputation: 126

Blazor does not currently send the id_token_hint. MS have been aware since .Net 5, but are yet to fix it. There's signs it could be fixed in .Net 8.

https://github.com/dotnet/aspnetcore/issues/29586

Upvotes: 1

Related Questions