What is Blazor? A Tutorial on Building Web Apps with Authentication

Hi Team,

Currently I am using auth0 and it is using the universal login. However could you please guide me how to change the flow to use the login pop up in blazor server. Any examples will be helpful.
I have used the article mentioned below for my current implementation.

Hi @rocku103,
Welcome to the Auth0 Community!

As far as I understand, you want to embed the login page in your Blazor application. Unfortunately, this is not a good practice for security reasons.
Please, take a look at this doc for more details.

Hi, thanks for your easy to understand post. As I am new to Auth0 so it will take time to understand deeply and implement the new things. But I am good in learning and implementing new things. If I have any issue in implementing then I will ask here. Thanks.

1 Like

No worries! Welcome here!

1 Like

Hey. Recently realized that if I logout of a Blazor server app on one browser tab, then any other tabs that are open (on different circuits) are still considered to be logged in. I think the way to handle this is a CustomAuthorizationStateProvider with something called RevalidatingServerAuthenticationStateProvider. I havenā€™t been able to figure out how to implement this with Auth0. I followed this article to implement security:

I now need to resolve the multiple tabs issue. Does anyone have any experience with this?

Many thanks

Hi, if I hit refresh after logging out using Blazor Authentication, the user is logged back in again. How can stop SilentAuth in this instance and force users to re-enter credentials after they log themselves out?

Hello @Ditchford,
As far as I know, this behavior is by design.
I havenā€™t tried to implement logout via RevalidatingServerAuthenticationStateProvider , but I found this Q&A on Stack Overflow that seems to implement it.
I hope it can inspire you :slightly_smiling_face:

Hey @kausti0,
Welcome to the Auth0 Community!

The issue you are reporting was a Blazor issue in the early releases. Honestly, I canā€™t reproduce it anymore :thinking:

What version of .NET are you using? Have you tried to download and test the sample project attached to this article?

I developped ASP.NET Blazor Web App in which I am using Auth0 for user authentification. When I run it from VisualStudio 2022 (after clicking on debug button), log in works fine. But when I create docker image and try to run it either locally using docker, or on Amazon ECS (ECR), the log in does not work.

It throws the default error page: Error.

An error occurred while processing your request.

Development Mode

Swapping to the Development environment displays detailed information about the error that occurred.

The Development environment shouldnā€™t be enabled for deployed applications. It can result in displaying sensitive information from exceptions to end users. For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development and restarting the app.

Here is my Program.cs code:

using DolphinParserBlazor.Data;
using Auth0.AspNetCore.Authentication; // new code
using System.Net;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Web;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<GcodeService>();
builder.Services
.AddAuth0WebAppAuthentication(options => {
    options.Domain = builder.Configuration["Auth0:Domain"];
    options.ClientId = builder.Configuration["Auth0:ClientId"];
});


var app = builder.Build();



// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication(); // new code
app.UseAuthorization(); // new code



app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

I used just the standard process for Auth0 authentification described in the manual. Any ideas how to solve the problem when trying to log in? I need to make it work when deployed and run as docker imageā€¦

Hi @daniel.puchta,
Welcome to the Auth0 Community!

The error message you are getting is a generic message. It tells you nothing about the actual error that is causing your application to fail.

You get this generic message because the Docker or Amazon ECR environments are not considered development environments, and so the code in your Program.cs file shows the content of the Pages/Error.cshtml page.

Please, take a look at this document to learn more about configuring multiple environments in ASP.NET Core.

Remember that in production environments, you should never show the actual error message on a web page. You must catch and log any exceptions that occur.

1 Like

Thank you very much for this tutorial!
I just tested it and it works well with my WindowsLive connection.
Except that the image of my profile is not uploaded : if I paste the returned URL ( https://apis.live.net/v5.0/xxxxxxxxxxxxx/picture ) it indicates that the API is not ok anymore

{
   "error": {
      "code": "api_deprecated", 
      "message": "This API is no longer supported. Please see https://aka.ms/livesdkmigration for information about migrating your application to Microsoft Graph."
   }
}

Hey @christophep,
Welcome to the Auth0 Community!

Honestly, Iā€™m not sure if this is a problem on our side or on the Microsoft side.
I will report it internally.
Thanks

3 Likes

Hi Andrea,
I really appreciate you continuing to respond to all these messages! I hope you find a lead. I canā€™t find it myself

2 Likes

Andrea - Thanks for putting this post together. Super helpful! Iā€™m building a Blazor Server app in .NET 7.0 and everything seems to be working great, except for one thing. The callback URL never appears to be called after a successful login. My code in Program.cs is:

builder.Services.AddAuth0WebAppAuthentication(o => {
    o.CallbackPath = "/auth0";
    o.ClientId = SettingsUtil.Settings.CellaretAdminAuth0ClientId;
    o.ClientSecret = SettingsUtil.Settings.CellaretAdminAuth0ClientSecret;
    o.Domain = SettingsUtil.Settings.Auth0Domain;
    o.Scope = "openid profile email";
});

When I put a breakpoint in my /auth0

OnGet()

method, it never gets hit. Any thoughts? Thanks!

Hey @cellaret,
The CallbackPath property is intended to be handled by the OIDC middleware. Its default value is /signin-oidc and you can change it just in case it conflicts with an existing endpoint in your application. Normally you donā€™t need to change it, and you canā€™t override its behavior anyway.

If your goal is to redirect the user to a specific page after login, you should specify the redirect URL using the redirectUri parameter.

Referring to the articleā€™s sample project, if you want to redirect your user to the /auth0 page, you need to change the AccessControl.razor component as follows:

<AuthorizeView>
    <Authorized>        
        <a href="logout">Log out</a>
    </Authorized>
    <NotAuthorized>
        <a href="login?redirectUri=/auth0">Log in</a>
    </NotAuthorized>
</AuthorizeView>

I hope everything is clear.

1 Like

This was fairly straightforward and I got it redirecting to my Blazor page endpoint /auth0, but now I am getting an odd OpenIdConnectAuthenticationHandler exception. It reads:

An unhandled exception occurred while processing the request.
Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
Unknown location

Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()

Stack Query Cookies Headers Routing
Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.

Show raw exception details
System.Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Show raw exception details
System.Exception: An error was encountered while handling the remote login.
 ---> System.Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Iā€™ve tried both a Blazor component/page and a .CSHTML page (with model) and both give the same error. Is there something extra that needs to be added to the Startup.cs class to make this work?

Iā€™ve even tried adding the following to my Startup.cs class with no effect:

builder.Services.AddHttpContextAccessor();

The code for my callback doesnā€™t even reach the breakpoint shown:

Thoughts?

Hey @cellaret,
To redirect users to a specific page, all you need to do is specify it in the redirectUri parameter.
If you use the Blazor project attached to my article and modify the AccessControl.razor component as follows, your users will be redirected to the quizViewer page instead of the home page:

<AuthorizeView>
    <Authorized>        
        <a href="logout">Log out</a>
    </Authorized>
    <NotAuthorized>
        <a href="login?redirectUri=/quizViewer">Log in</a>
    </NotAuthorized>
</AuthorizeView>

Nothing else is required.

It seems that your error is related to the OpenID Connect middleware. Make sure it is configured correctly. Did you remove the CallbackPath setting?

Also, be careful with using HttpContextAccessor in Blazor Server (see this). BTW, there is a typo in the code highlighted by your breakpoint (HttpContextAccssor instead of HttpContextAccessor )

To access your user data, you should use the authentication state, as shown in the article.

1 Like

Iā€™m pretty sure there is a bug here somewhere. Hear me out.

When I setup my component as you suggest:

<AuthorizeView>
    <Authorized>
        <ProfileMenu />
    </Authorized>
    <NotAuthorized>
        <RadzenLabel>
            <a href="/login?redirectUri=/auth0">Log In</a>
        </RadzenLabel>
    </NotAuthorized>
</AuthorizeView>

The Auth0 login page fails - it says that I have incorrectly configured my Callback URL. I have configured mine to be: https://localhost:7203/auth0. But here is my Auth0 login screen:

Now, if I modify my Program.cs file to include the callback in the options:

// Add Authentication...
builder.Services.AddAuth0WebAppAuthentication(o => {
    o.CallbackPath = "/auth0";
    o.ClientId = SettingsUtil.Settings.CellaretAdminAuth0ClientId;
    o.Domain = SettingsUtil.Settings.Auth0Domain;
    o.Scope = "openid profile email";
});

I get an error upon successful login when Auth0 attempts to callback to my razor page:

Soā€¦ In order to fix all of this, I have to do something odd. I have to add a Callback URL into my Auth0 application settings that doesnā€™t exist: https://localhost:7203/callback. Once this is configured on the Auth0 side, the application does load the /auht0 razor page as specified in the <AuthorizedView> element.

It would appear the bug is that when the login.cshtml razor page is invoked and the OnGet() method executes:

public async Task OnGet(string redirectUri)
{
    var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
        .WithRedirectUri(redirectUri)
        .Build();

    await HttpContext.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
}

The redirectUri param is not properly sent to Auth0 in the request. Either way, it would seem bad practice to have to configure my Auth0 application in such a way that the Callback URL is a page that does not exist.

Am I missing something here or does this make sense?

Hey @cellaret,
What you think is a bug is actually the standard behavior of the ASP.NET Core authentication middleware that the Auth0 SDK relies on.

Basically, the value of the redirectUri parameter (and the corresponding redirectUri property) is NOT the redirect_uri parameter you find in the authorization request URL.

The former is the page to which you want your user to be redirected. It is handled internally in your application through the authentication middleware. Auth0 doesnā€™t know this URL

The latter is where Auth0 sends the ID token after the authentication. Auth0 needs to know this URL and it should be registered in the dashboard.
This URL is defined and fully handled by the authentication middleware.
As mentioned before, the default value is /signin-oidc. Our SDK only redefines it as /callback for consistency with the other SDKs.

In summary, you must register https://localhost:7203/callback in the Auth0 dashboard regardless of what page you want your authenticated user to land on.

I hope that this clarifies the internal behavior :slightly_smiling_face:

OK, still clicking along with an app that I have decided to do as a Blazor WASM app. Anyway also been off an on trying out Auth0 and find it pretty straight forward. I went through this entire example and it ran like a champ. But after some examples I tried on Amazon Amplify thought letā€™s try this there. I think my problem is with the Callback URI and the Logout URI. Has anyone done this?