Open Closed

Permission checker #627


0
alexander.nikonov created

3.3.1 / Angular

Hi ABP team.

I created solution as an ABP module. At this moment i would like to check for permissions which were granted for a user's roles. I'm using IsGrantedAsync method of IPermissionStore interface. But this method returns negative result every time. I'm using "* .HttpApi.Host" project to run and test my solution.

Also I've found out that information about user isn't complete: the user's roles are absent in CurrentUser member of ApplicationService object, but access token contains this data.

Could you please suggest what I did wrong and how it can be fixed? I would like to add a custom provider name like "Q", what am I supposed to do in this case and how to make IPermissionStore interface methods work with a new provider name?


25 Answer(s)
  • 0
    albert created
    Support Team

    do you have typeof(AbpPermissionManagementEntityFrameworkCoreModule), in your DependsOn attribute in Host project

  • 0
    alexander.nikonov created

    Yes, it's there:

  • 0
    albert created
    Support Team

    hi, I guess you are using the seperated identity server architecture. it seems like the, there's an issue about retreiving the role claims. when there's no role claims, permissions are not working properly.

    this is most probably an Identity Server configuration issue. I'll try to reproduce it in my local.

  • 0
    alexander.nikonov created

    You are right. I'm using separate Identity Server. All Identity Server configuring has been done. I'm using simple Authorize attribute without any permission as extra parameters and I didn't find any mistakes in my log related to Identity Server. Looking forward for your findings.

  • 0
    albert created
    Support Team

    I tried with a new 3.3.2 project and it works if you are starting the request from swagger, you need to authorize it via swagger

  • 0
    alexander.nikonov created

    Hi,

    I'm not using swagger in this case. I built Angular application based on ABP template. This application can authorize user and send request to several services. As you can see below in the picture, access token has been parsed and information about user and their roles is present. What is the reason IPermissionStore may return incorrect result?

  • 0
    albert created
    Support Team

    do you see granted policies for this user

    https://localhost:44328/api/abp/application-configuration

  • 0
    alexander.nikonov created

    I couldn't check permissions in my business logic in "Service 2" (see our current workflow picture attached below). Both services have connection to the same DB. I've attached pictures in my first post, where you can notice that property CurrentUser of AppService object doesn't contains any roles for this user. But If I open AuthorizeService in my controller, access token is parsed and claims with roles are present (see picture in prev post).

  • 0
    maliming created
    Support Team

    hi @alexander.nikonov

    Can you use the template project to reproduce the problem and share it with me? [email protected]

  • 0
    alexander.nikonov created

    Hi @maliming.

    We found out that our project contains mix of commercial and free libraries. It has been fixed, but issues of using IPermissionStore remained. I've generated ABP module project to reproduce the issue as you had asked me. Don't forget: that project is run separately and connected to IdentityServer which is run separately too and it is not a part of this project. So Abp.PermissionStoreTest.IdentityServer project was unloaded and didn't take part in the testing. I didn't manage to find source code of Volo.ABP.Authorization NuGet package (version 3.3.2). Could you please tell me where it is located or share one with me via attachment?

    Please check your e-mail for the project's source code + screenshots.

    Looking forward for your reply.

  • 0
    maliming created
    Support Team

    hi

    Could you please tell me where it is located or share one with me via attachment?

    https://github.com/abpframework/abp/tree/dev/framework/src/Volo.Abp.Authorization

    I will check your email asap. : )

  • 0
    maliming created
    Support Team

    hi

    Can you share some steps? and your project is using Oracle. I only have sql server.

    Thanks. Regards

  • 0
    alexander.nikonov created

    Hi.

    We found out that the class which implements IPermissionStore interface has different behavior than we expected. This class has limitation on checking granted permission. It can check any permission which was declared in current ABP module for some roles, but due to the limitation, it doesn't allow to check granted permission which was declared in other module for the same roles.

    Also please pay attention to property CurrentUser. As you can see, this property returns object with information about the user who sent request. And the field UserName is null. Could you please explain how it can be fixed or what we did wrong? This field is required for us.

  • 0
    maliming created
    Support Team

    hi @alexander.nikonov

    Your situation is complicated, I cannot confirm the problem,

    Can you use the template project to reproduce the problem and share it with me? [email protected]

  • 0
    alexander.nikonov created

    We would like to have permission mechanism on top of existing permission architecture.

    For instance, current tenant's company have bound licences, each of licence determines which UI pages ("modules") are accessible for current user. Thus, is the logged-in user has no access to the given page - it has to be hidden from UI navigation route - even before checking the given app / role permissions.

    How to implement this mechanism?

    I've tried to override existing ABP PermissionChecker class, doing my licence check there in IsGrantedAsync, but such approach does not look fully right: I am getting error 403 if there is no access, but instead I need to have the menu item completely hidden from my Angular app navigation route. I need backend mechanism which works for both backend and frontend part.

  • 0
    maliming created
    Support Team

    hi

    I think you can add a LicencesPermissionValueProvider to implement your logic instead of override the PermissionChecker class.

    After that, the menu will be hidden/show base on the permissions.

    https://docs.abp.io/en/abp/latest/Authorization#advanced-topics

    https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs#L7

  • 0
    alexander.nikonov created

    @maliming thank you, i've tried this, but did not succeed:

    Issue #1:

    when user is logged in, for some reason context.Permissions is empty here, so I am getting exception (while a user is not logged in - the context.Permissions contains all proper data):

    public override async Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
            {
                var moduleId = _abxRequestContext.AbxModuleId;
    
                var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToArray(); // context.Permissions is empty!
    

    Issue #2:

    I need to get access to custom data for my navigation menu items: meanwhile we use custom field - moduleId - to pass the accessed page information to server (moduleId is written to our custom IAbxRequestContext object via our middleware and and eventually is logged to DB table and used in other places). This field was also supposed to be used to identify the page to access via licence permission. But of course PermissionValuesCheckContext does not contain this data from Angular routing item. Neither IAbxRequestContext object data is available yet. So how to pass data from navigation menu to CheckAsync method and decide on what to display and what - not to display?

    Issue #3:

    is there some ABP cache mechanism to be consumed for caching licence data? Otherwise we would need to re-read this data from DB via appservice each time CheckAsync is called.

    p.s. since we seem to have a noticeable timeshift and not able to correspond in real-time - please provide me with as much detailed answer as possible so i could analyze this approach and find out what's wrong now...

  • 0
    maliming created
    Support Team

    Issue #1

    Can you try the latest? 4.3.2

    issue #3

    https://docs.abp.io/en/abp/latest/Redis-Cache

  • 0
    maliming created
    Support Team

    Issue #2:

    The angular permission check happens locally, the server will check all the permissions of the current user or user's role etc and return to angular.

    The menu just checks whether the permission is granted.

  • 0
    alexander.nikonov created

    Can you try the latest? 4.3.2

    I've tried 4.3.2 and now Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context) is not triggered at all for a logged user: is it correct behavior? When it needs to be triggered??

    The angular permission check happens locally, the server will check all the permissions of the current user or user's role etc and return to angular. The menu just checks whether the permission is granted

    Yes, I understand - but how to extend "permissions" functionality and use some custom things like our moduleId in our licence provider?

  • 0
    maliming created
    Support Team

    is it correct behavior? When it needs to be triggered??

    For instance, current tenant's company have bound licences, each of licence determines which UI pages ("modules") are accessible for current user.

    You can create some permissions, Don't grant to users or user roles. Then your custom PermissionValueProvider will be triggered.

    You can check the current tenant's company licences to return true or false, angular will show/hide the menu according to this value.

    https://docs.abp.io/en/abp/latest/Authorization#advanced-topics

  • 0
    alexander.nikonov created

    You can create some permissions

    We have a list of module IDs (each module can be considered as a separate page in navigation menu) and we would prefer not to mix that with "permissions", since it's another conception. And we would like to use it in parallel with requiredPolicy as shown in screenshot:

    ModuleId needs to be checked in Licence Provider and decide whether the given user has access to the given module ID (page): if not - the page is not displayed in the navigation menu neither user can access data for it.

  • 0
    maliming created
    Support Team

    hi

    It is currently impossible. : )

  • 0
    alexander.nikonov created

    @maliming

    Actually i've managed to achieve this, but using slighly different approach: i've overriden a couple of classes, where filtered existing permissions, but using licence rules:

        [Dependency(ReplaceServices = true)]
        [ExposeServices(typeof(IPermissionAppService))]
        [Authorize]
        public class CentralToolsPermissionAppService : PermissionAppService
        
        public class CentralToolsRolePermissionValueProvider : RolePermissionValueProvider
        
    

    This way I get the filtered roles in the menu and in the Role Permission management. I am not sure we would use Client Permission Management for clients, but then probably I would need to override that provider too.

    Possibly I am missing something??

    Another approach - to use client-side changes: to override RoutesService and PermissionGuard in Angular app - so they would react on licence rules: so menu items will be filtered out and service access will be restricted based on these rules...

    Are existing permissions are cached somehow by ABP? BTW, we do not use Redis so far and still not planning too... So if it's about caching - we will use something simple built-in...

  • 0
    maliming created
    Support Team

    hi

    The framework will use memory cache if you don't use Redis. It caches permissions related instead of querying the database multiple times

    https://docs.abp.io/en/abp/latest/Caching https://docs.abp.io/en/abp/latest/Redis-Cache