Open Closed

Custom-PermissionValueProvider-doesn't-work-for-MultipleResults-when-using-Authorize-attribute #8918


User avatar
0
maksym created
  • ABP Framework version: v7.3.3

  • UI Type: Blazor Server

  • Database System: EF Core SQL Server

  • Tiered (for MVC) or Auth Server Separated (for Angular): Tiered

  • Exception message and full stack trace:

API HOST side

image.png

Blazor Side

image.png

  • Steps to reproduce the issue:

We created a custom PermissionValueProvider for our specific requirements, and even though the CheckAsync functions appear to return correct result values, it still fails with Forbidden error.

The curious thing is that permissions are required for the user for the menu items, so if I add scopes (our permission system) to the user, the ScopedRolesPermissionValueProvider properly
add those permissions to the user and the user is now able to see the menu items.

But if we run api calls that use the Authorize attribute, it fails with the Forbidden error.

code for custom PermissionValueProvider:

public class ScopedRolesPermissionValueProvider : IPermissionValueProvider, ITransientDependency
{
    public string Name => "ScopedRolePermission";
    private const string ADMIN_CLIENT_ID = "Fixhub_Web";

    private readonly IServiceProvider _serviceProvider;

    public ScopedRolesPermissionValueProvider(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public async Task CheckAsync(PermissionValueCheckContext context)
    {
        var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value;

        if (clientId is null || clientId == ADMIN_CLIENT_ID)
        {
            return PermissionGrantResult.Undefined; // We should let other PermissionValueProvider decide...
        }

        var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;
        if (userId == null)
        {
            return PermissionGrantResult.Undefined;
        }

        IPermissionContextManager permissionContextManager =
            _serviceProvider.GetRequiredService();
        PermissionGrantResult permissionGrantResult =
            await permissionContextManager.IsScopeGrantedAsync(userId, context.Permission?.Name);

        return permissionGrantResult;
    }

    public async Task CheckAsync(
        PermissionValuesCheckContext context
    )
    {
        var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToArray();

        Check.NotNullOrEmpty(permissionNames, nameof(permissionNames));

        var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;

        if (userId == null)
        {
            return new MultiplePermissionGrantResult(permissionNames);
        } // Returns all permissions as Undefined.

        IPermissionContextManager permissionContextManager =
            _serviceProvider.GetRequiredService(); // as PermissionContextManager;
        return await permissionContextManager.IsScopeGrantedAsync(userId, permissionNames);
    }
}

extension method for IsScopeGrantedAsync:

public static async Task IsScopeGrantedAsync(
	this IPermissionContextManager manager,
	string userId,
	string[] permissionNames
)
{
	var scopedRolesAllowedPermissions = await manager.GetUserCurrentScopedPermissions(userId);

	var result = new MultiplePermissionGrantResult();

	foreach (var item in permissionNames)
	{
		result.Result.Add(
			item,
			item != null && scopedRolesAllowedPermissions.Contains(item)
				? PermissionGrantResult.Granted
				: PermissionGrantResult.Undefined
		);
	}

	return result;
}

Results returned seem good:

image.png

How we add the dependency in our ApplicationModule.cs file

image.png

Basically browsing any page that either has the [Authorize] attribute or that calls an api endpoint that has the [Authorize] attribute fails with forbidden even if the user seems to have all the correct permissions assigned by our custom permission value provider.

This only happens through the blazor UI. Going directly through the API is perfectly fine. We even have a completely separate ReactJS app that connects to those endpoints and it works fine.


3 Answer(s)
  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    Hi, I will check and let you know asap.

    Regards.

  • User Avatar
    0
    maksym created

    I created a new Tiered Blazor project and added a custom permission value provider that simply returns all permissions as granted and it worked fine.

    But in our current solution, even the "grant all" approach has the same error.

  • User Avatar
    0
    maksym created

    It seems that the actual error came from the singular permission grant check and from returning undefined when for the blazor app.

    Removing this code seems to have fixed the issue (this is code that used to be useful, but not anymore, in our codebase).

    image.png

    Closing for now, as long as the issue has been resolved.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.2.0-preview. Updated on March 13, 2025, 04:08