dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.41k stars 10k forks source link

Regression: HTTP 401 When refreshing page using MS Entra ID Auth (Blazor - WASM + Server) #52586

Open sh-jthorpe opened 10 months ago

sh-jthorpe commented 10 months ago

Is there an existing issue for this?

Describe the bug

When refreshing a Blazor page that has @attribute [Authorize], the browser gives a HTTP 401, even though the user is logged in.

Similar to https://github.com/dotnet/aspnetcore/issues/52317, but we're not using a custom auth provider. We're using MS Entra ID as per the .NET 7 docs https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-microsoft-entra-id?view=aspnetcore-7.0. This issue was introduced when migrating the project to .NET 8.

Expected Behavior

It should load the page.

Steps To Reproduce

dotnet new blazorwasm -ho -au SingleOrg --api-client-id "{api-client-id}" --app-id-uri "{app-id-uri}" --client-id "{client-id}" --default-scope "API.Access" --domain "{domain}" -o "Project" --tenant-id "{tenant-id}" --framework net7.0

Exceptions (if any)

No response

.NET Version

8.0.100

Anything else?

The article https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-microsoft-entra-id?view=aspnetcore-7.0 was removed from the .NET 8 docs.

I've read https://github.com/dotnet/aspnetcore/issues/52317#issuecomment-1824624057, but it's not clear how that applies to MS Entra ID auth, and since there's no documentation on this scenario anymore, It's not clear what to do.

Prerendering is disabled: App.razor

<HeadOutlet @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)"/>
...

<Routes @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />

My App.Razor is in the server project, my Routes.Razor is in the Client project

halter73 commented 8 months ago

I suspect the issue is that the new Blazor routing model used by MapRazorComponents<App>() relies on endpoint routing, so you we need to be able to authenticate the initial request to the server using cookies generated from a server-side OIDC flow using AddMicrosoftIdentityWebApp or AddOpenIdConnect.

That being said, if you want to continue using the previous routing system, you can continue using UseBlazorFrameworkFiles and MapFallbackToFile("index.html") to do the client-side OIDC, and simply update the TargetFramework in your csproj to net8.0 all of the old APIs should still be supported.

Steps To Reproduce

dotnet new blazorwasm -ho -au SingleOrg --api-client-id "{api-client-id}" --app-id-uri "{app-id-uri}" --client-id "{client-id}" --default-scope "API.Access" --domain "{domain}" -o "Project" --tenant-id "{tenant-id}" --framework net7.0

Given that you've already done this, can you please provide what you've done so far?

halter73 commented 6 months ago

Calling MapRazorComponents<App>().AllowAnonymous() might also work if you have the <AuthorizeRouteView> set up correctly. Take a look at https://github.com/dotnet/aspnetcore/issues/53732#issuecomment-2021878231 for more details.