question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Blazor Server AuthorizeView rendering NotAuthorized before AuthorizationHandler finishes executing

See original GitHub issue

I’m trying to implement a custom AuthorizationHandler that uses business rules to determine whether or not a user has access to a certain page.

To do that I implemented the following:

CustomMemberHandler.cs

public sealed class CustomMemberHandler: AuthorizationHandler<CustomRequirement, long?>
{
	public override async Task HandleAsync(AuthorizationHandlerContext context)
	{
		if (context.Resource == null || context.Resource is long)
		{
			foreach (var requirement in context.Requirements.OfType<CustomRequirement>())
			{
				await this.HandleRequirementAsync(context, requirement, (long?)context.Resource);
			}
		}
	}

	protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement, long? resourceId)
	{
		var userId = context.User.GetUserId();

		if (userId.HasValue && resourceId.HasValue && await <Database Invocation>)
		{
			context.Succeed(requirement);
		}			
		else if (logId.HasValue == false)
		{
			context.Succeed(requirement);
		}
		else
		{
			context.Fail();
		}
	}
}

Startup.cs

services.AddAuthorization(options =>
{
	options.AddPolicy(PolicyConstants.CUSTOM_POLICY, policy =>
	{
		policy.RequireAuthenticatedUser();
		policy.Requirements.Add(new CustomRequirement());
		policy.Build();
	});
});

services.AddTransient<IAuthorizationHandler, CustomMemberHandler>();

And in my component I’m using the following:

BlazorPage.razor

@inherits OwningComponentBase

<AuthorizeView Policy="@PolicyConstants.CUSTOM_POLICY" Resource="@this.Id">
	<Authorized>
		<PageLayout/>
	</Authorized>
	<NotAuthorized>
		<HandleNotAuthorized/>
	</NotAuthorized>
</AuthorizeView>

The HandleNotAuthorized component redirects the user to the AccessDenied page.

I also have an AuthorizeRouteView that’s used in the App.razor file.

<CascadingAuthenticationState>
	<Router AppAssembly="@typeof(Program).Assembly">
		<Found Context="routeData">
			<AuthorizeRouteView RouteData="@routeData">
				<NotAuthorized>
					<HandleNotAuthorized />
				</NotAuthorized>
			</AuthorizeRouteView>
		</Found>
		<NotFound>
			<HandleNotFound />
		</NotFound>
	</Router>
</CascadingAuthenticationState>

What is happening is that the NotAuthorized fragment is being rendered even though the AuthorizationHandler hasn’t executed yet (or at least hasn’t finished executing). This causes the user to be redirected to the AccessDenied page even though the AuthorizationHandler executes succesfully.

Is this behaviour normal?

Further technical details

  • ASP.NET Core 3.1.4
  • Microsoft Visual Studio Community 2019 Version 16.6.2
.NET Core SDK (reflecting any global.json):
 Version:   3.1.301
 Commit:    7feb845744

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.301\

Host (useful for support):
  Version: 3.1.5
  Commit:  65cd789777

.NET Core SDKs installed:
  3.0.103 [C:\Program Files\dotnet\sdk]
  3.1.102 [C:\Program Files\dotnet\sdk]
  3.1.300 [C:\Program Files\dotnet\sdk]
  3.1.301 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
juho-hanhimakicommented, Apr 8, 2021

This issue is quite painful. Please consider fixing this!

My custom AuthorizationHandler makes API calls and <NotAuthorized> is shown on the AuthorizeView instead of <Authorizing> while the handler is still processing. This is certainly a bug.

2reactions
zbecknellcommented, Jul 29, 2020

Had a similar issue to this. I ended up putting up a hack, as we’d briefly have “Not Authorized” flash up before the authorized content showed (in some scenarios), so I just put in a base wait period for my unauthorized view, like so:

@page "/_unauthorized"
@layout EmptyLayout

@if (isWaiting)
{
    <Loader /> <span class="ml-2">Authorizing...</span>
}
else
{
    <h1 class="text-danger">Unauthorized.</h1>
    <h2 class="text-danger">I'm sorry, you're not authorized. If you believe this is an error, please contact a system administrator.</h2>
}

@code {
    // HACK: we are giving the auth system a little time to catch up and make sure we aren't authorized
    // We have certain scenarios where Unauthorized will flash during the auth process
    bool isWaiting = true;

    protected async override Task OnInitializedAsync()
    {
        await Task.Delay(2000);
        isWaiting = false;
    }
}

It doesn’t solve the underlying problem but it does the trick for us, for now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Why does Server Side Blazor's <AuthorizeView> not ...
I have created a Blazor server project using Windows Authentication ... after the app re-renders and displays the "NotAuthorized" content.
Read more >
ASP.NET Core Blazor authentication and authorization
Client-side markup and methods associated with an AuthorizeView are only protected from view and execution in the rendered UI in Blazor ...
Read more >
Configuring Policy-based Authorization with Blazor
In this post, I describe policy-based authorization and it's advantages over the more legacy role-based authorization.
Read more >
Different ways of Authorization in Blazor + Redirect To Login ...
The first basic version of authorization in Blazor is using AuthorizeView for a simple user signed in check. AuthrozieView works base on the ......
Read more >
Custom Authentication in Blazor WebAssembly - Step-By- ...
Let's a mode for our User. Since this Model will inherit from IdentityUser, we will be adding it to the Server Project. But...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found