Search code examples
authorizationasp.net-identityblazor-server-side

Blazor Server with Identity permissions authorization redirect loop


So, I have a new Blazor .net 6 Application that is using .net Identity for authentication. I was attempting to implement permissions based authorization by following this tutorial. As far as I can tell I have everything set up correctly, but when I start the app I'm immediately greeted with a redirect loop, a an error that reads "The page isn't redirecting properly" and a URL that's about 2600 characters long (https://localhost:7121/Identity/Account/Login?ReturnUrl=%252FIdentity%252FAccount%252FLogin%253FReturnUrl%253D%25252FIdentity%25252FAccount%25252FLogin%25253...).

error message

As part of the tutorial I added two services to my Program.cs.

builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>(); // Redirect error goes away if this is commented out
builder.Services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();

If I comment out the PermissionPolicyProvider line, the redirect goes away and I can log in but I have no authorization. If I comment out PermissionPolicyProvider, log in, uncomment PermissionPolicyProvider and restart the app, the authorization works, but as soon as I log out I immediately get the redirect error. The error shows up when accessing pages that have [Authorize] and pages that have [AllowAnonymous].

Here is the PermissionPolicyProvider:

public class PermissionPolicyProvider : IAuthorizationPolicyProvider
{
    public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }

    public PermissionPolicyProvider( IOptions<AuthorizationOptions> options )
    {
        FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider( options );
    }

    public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();

    public Task<AuthorizationPolicy> GetPolicyAsync( string policyName )
    {
        if ( policyName.StartsWith( CustomClaimTypes.Permission, StringComparison.OrdinalIgnoreCase ) )
        {
            var policy = new AuthorizationPolicyBuilder();
            policy.AddRequirements( new PermissionRequirement( policyName ) );

            return Task.FromResult( policy.Build() );
        }

        return FallbackPolicyProvider.GetPolicyAsync( policyName );
    }

    public Task<AuthorizationPolicy> GetFallbackPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
}

There is a redirect in my App.razor file that redirects unauthenticated users, the redirect was working fine and I still get the redirect error even if I remove the redirect from App.razor. At this point I'm not really sure where to look. Is there something I may be overlooking when I implement the PermissionPolicyProvider?


Solution

  • Changing this:

    public Task GetFallbackPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
    

    to this:

    public Task GetFallbackPolicyAsync() => FallbackPolicyProvider.GetFallbackPolicyAsync();
    

    fixed the issue.