Securing Blazor WebAssembly Apps

@al-cashbucket, I’m going to ask internally to learn more about this hypothesis

2 Likes

Hi @stevchik,
Welcome to the Auth0 Community :wave:

It is not easy to figure out what might be causing the error without having the code and configuration available.
For example, you didn’t share how authentication is configured on your Blazor WASM app.
Maybe I’m wrong, but the HttpClient configuration you shared doesn’t look like it’s injecting the access token :thinking:

It looks like you didn’t follow this article’s guidelines for setting up your Blazor WASM app. If so, I suggest you follow them.

Also, have you tried to decode your access token through jwt.io to check if the relevant data is as expected (.e.g., issuer)?

Happy to help if you can provide more details/code

2 Likes

Hey @al-cashbucket, I received confirmation that there are no restrictions on custom parameters on the Auth0 side. My colleague also suspects that this is a Blazor bug.

2 Likes

Hey @andrea.chiarelli
I’m using Social Login (Google) in my blazor web assembly app in a aspnet core hosted model.
I have created a custom role in Auth0 console and have assinged one user that role.
I’ve created the AuthorizationPolicy and in its handler I check for the user Role
Below is the code of my handler class

public class OnlySuperAdminHandler : AuthorizationHandler<OnlySuperAdminRequirement>
{
    /// <summary>
    /// This handler is used to check if the user belongs to SuperAdmin role
    /// </summary>
    /// <param name="context"></param>
    /// <param name="requirement"></param>
    /// <returns></returns>
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OnlySuperAdminRequirement requirement)
    {
        if (context.User.Identity?.IsAuthenticated == true)
        {
            if (context.User.HasClaim("role", "SuperAdmin"))
            {
                context.Succeed(requirement);
            }
           
        }
        return Task.CompletedTask;
    }
}

This authorization condition is failing though the logged in user belogns to SuperAdmin role.
Can you please guide me if I’m missing anything over here.

Thanks.

Hi @goldytech,
I’m afraid I need additional information to have a clear understanding of your scenario.

You say your Blazor WebAssembly app uses the hosted model. Do you also have an API? Does this role check happen on the Blazor WebAssembly or on the API side?

Have you created an Action to add the roles to the ID token or the access token?

Assuming the authorization check happens on the Blazor side, are there any specific reasons you are using the custom policy-based approach instead of the simpler role-based authorization approach?

In case you actually need the custom policy-based approach, how do you configure and use the policy in the Blazor app?

If you can share even a simplified version of your app, I can try to get a closer look at its code to understand what is going on.

2 Likes

Thanks for your response @andrea.chiarelli
Below are the responses for your questions

You say your Blazor WebAssembly app uses the hosted model. Do you also have an API? Does this role check happen on the Blazor WebAssembly or on the API side?

Yes, an ASPNet Core project hosts webassembly and has the REST APIs in the same project. My first intent is to use the roles on the Blazor side, as I need to show/hide UI components based on the logged-in user’s role. I’ve written a custom authorization policy on the client side for this. In future, I may write the same policy on the server side to protect the APIs

Thanks for this I will try it , though I prefer to use policy based authorization as it will give me granular control on authorization in future if the requirement changes and the stakeholders demand for attribute/permission based rather RBAC

I have followed this blog post in doing this implementation

Thanks once again for your support.

Best,
goldytech

Hi @goldytech,
Thank you for the info. It clarifies your intent.

However, you didn’t tell me if you created an Action to add the roles to the ID token or the access token. This is crucial, because ID and access tokens issued by Auth0 don’t include roles by default.

If you created this Action, make sure that the user’s roles are included in your token. You can use this tool to decode your JWT token and see if they are included.

Also, be sure to check the exact name of the claim in the token. I mean, if you create a claim named “https://my-app.example.com/roles” (best practices require using a namespace), you should check for that exact name:

context.User.HasClaim(“https://my-app.example.com/roles”, "SuperAdmin")

As an alternative, you could use claim mapping, but I don’t want to make things too complicated.
By the way, the role claim is usually an array (a user can have multiple roles), so you should take this into account when checking it.

Again, without a sample code it’s hard to figure out why your code is not working.

2 Likes

Thanks, @andrea.chiarelli. Yes, it is working after adding Post Login Actions and adding custom claims in it.

1 Like

Great to hear this, @goldytech!

1 Like

I have been following the example posted here “SECURING BLAZOR WEBASSEMBLY APPS”

I am using the concepts and steps in nearly identical project based off the template 'heroplate found here

The problem I have is that this heroplate project uses for it’s Layout, a “BaseLayout.razor”
image.

This is the component that actually contain the ‘@body’ tags that Auth0 is looking for.

When I have everything set up and made the changes need to make Auth0 work (refer to blog link above) I see this error in the browser tools.

Question: Is there anything I can do to make Auth0 work in my scenario of having a ‘BaseLayout’ that contains the @body tag(s)?

Thanks!

Error

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Object of type ‘Heroplate.Admin.Application.Layout.MainLayout’ does not have a property matching the name ‘Body’.
System.InvalidOperationException: Object of type ‘Heroplate.Admin.Application.Layout.MainLayout’ does not have a property matching the name ‘Body’.
at Microsoft.AspNetCore.Components.Reflection.ComponentProperties.ThrowForUnknownIncomingParameterName(Type targetType, String parameterName)
at Microsoft.AspNetCore.Components.Reflection.ComponentProperties.SetProperties(ParameterView& parameters, Object target)
at Microsoft.AspNetCore.Components.ParameterView.SetParameterProperties(Object target)
at Microsoft.AspNetCore.Components.ComponentBase.SetParametersAsync(ParameterView parameters)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)

Hi @ccre-support,
Welcome to the Auth0 Community!

From what I can see, I don’t think the error you get is related to the Auth0 integration. It looks like a UI-related issue.
I suggest running the application without the Auth0 integration and then adding one piece at a time to isolate the step that breaks the UI rendering.

By the way, be aware that the article you are referring to is an unauthorized copy of the article published on the Auth0 blog.

2 Likes

I’m looking at adding an option to alert users when their session is about to expire, allowing them to extend their session should they choose so. The application is a Blazor WebAssembly application, so it could be C# (preferable) or JS code.

I’ve found some information on JS option using getTokenSilently but I’m not using JS SDK, but .NET. Auth and Management SDKs.

Alternatively, I considered looking at the information stored in the JWT token as expires_at and alerting based on the expiration date/time found in the token by calling the app’s server side.

I would appreciate pointers in the right direction on how to build this feature. Thank you.

An important thing to understand is that, in general, your application’s session duration is independent of Auth0’s session duration.
Your application is responsible for managing its session, including its session duration.
Read this document to understand that different levels of sessions are involved here.

However, if you want to tie the duration of your session to the expiration of the ID token (note, ID token, NOT access token), you should periodically check its expiration and alert the user when it is about to expire.

If you are calling a protected API, the problem you may encounter is that the access token may expire before the ID token, forcing you to ask the user to authenticate again even though the session has not expired.
To handle this problem, you must use refresh tokens. In fact, the getTokenSilently() method for JS SPAs requests a new access token using a refresh token.

Read this article to learn more about refresh tokens. This article is specific for ASP.NET Core applications.

In this case, you must first enable refresh token support in your API. Then your Blazor WASM application must use refresh tokens to get a new access token as soon as the current one expires. I don’t have a specific example of how to use refresh tokens in Blazor WASM, but you can take inspiration from this section of this article for a practical example.

I know there’s a lot of stuff, but I hope I’ve given you an idea of how to proceed.

2 Likes

Hi all,

Just had a fun time troubleshooting why the protected API part was not working for me.

If you find yourself getting a 500 response from the protected API call, check you haven’t doubled up on the “https://” in the domain.

In the tutorial it tells you to protect the API using this:

Notice, the concat for “https://”. I then also had it in my config file as per this:

Hope this helps someone or promps a quick adjust to content :slight_smile:

Hi @WaywardVentures,
Welcome to the Auth0 Community and thank you for sharing your experience.

Just to clarify, the tutorial tells you to use your Auth0 domain in appsettings.json. A domain is NOT a URL, so it shouldn’t have https:// in it :slightly_smiling_face:

For more info, see this article.

1 Like

A final update on the Blazor/Auth0 Logout issues to mention that this is now resolved as Auth0 has added OIDC conformant logout per Use the OIDC Endpoint to Log Users Out of Auth0

At the moment you need to reach out to Auth0 support to get end_session_endpoint added to your metadata, with a toggle being added to the UI in the future. I’ve done this myself and can confirm it works as intended.

Once enabled you can remove any logout workarounds and use Navigation.NavigateToLogout("authentication/logout"); with a custom redirect or any of the other dynamic auth features.

1 Like

Thank you for sharing :pray:
It is in my plans to update the tutorial with this note soon

I have a Blazor Server web application and can’t find how to access user_metadata fields upon login?

Hey @MountainTopTech,
To access user_matadata you have several approaches.

One of these approaches is based on Actions. For example, you can create an Action to handle the PostLogin trigger. This action can access the event.user.user_metadata object and add the user metadata to the ID token as custom claims.

I hope this helps.

Hello everything is fine? So I’m venturing into blazor with authentication with Auth0. So I have a Blazor Wasm application and a .NET API.
The two are authenticating, I can log into the blazor and I can make requests to the API with the bearer generated in Auth0.
However, when Blazor makes a request, it fails and returns the HTTP 401 code, I believe it is unable to fetch the token to authenticate. If you can help me, I’ll put some pictures here to improve the help. Thanks a lot in advance! Very good article.

I don’t know if the problem could be the Audience that I put in Auth0 as Localhost.

  • Blazor -

Program.cs

Page.razor