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.

Authorization failure in constructor of AppService

See original GitHub issue
  • Your Abp package version: 3.5.0
  • Your base framework: .Net Framework or .Net Core: 2.0.1

Description:

Adding AbpAuthorizeAttribute to an app service that calls setters in its constructor will fail to proxy unless the user has been granted the permission required by the authorize attribute on the class.

To reproduce:

[AbpAuthorize("Users.Update")]
public class UserAppService : AsyncCrudAppService<User, ...>
{
    public UserAppService(/*omitted for brevity*/) 
    {
        // The call to `set_UpdatePermissionName` here is what throws the authorization exception.
        UpdatePermissionName = "Users.Update";
    }
}

public class SomeController
{
    private readonly UserAppService _userAppService;

    public SomeController(IUserAppService userAppService)
    {
        _userappService = userAppService;
    }

    // This method should be able to execute without the "Users.Update" permission
    public IActionResult ShouldWorkAction()
    {
        /* Does not require _userAppService */
    }

    [AbpAuthorize("Users.Update")]
    public IActionResult OtherAction()
    {
        /* Uses a _userAppService method */
    }
}

In the example above OtherAction is the only method requiring the UserAppService instance. Obviously, if the user has the requisite permissions, the controller will instantiate without a problem. The issue arises when the user has not been granted “Users.Update”. The failure occurs when Castle’s AbstractInvocation is intercepted by the Abp’s AuthorizationInterceptor during the call to the set_UpdatePermissionName method, causing a ComponentActivatorException.

I believe what should happen, is the constructor should be able to call whatever methods it needs (since they should not have side-effects in practice), without being intercepted.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
acjhcommented, Oct 5, 2018

This works with existing syntax and no need to replace IAuthorizationHelper:

[AbpAuthorize("Users.Update")]
public class UserAppService : AsyncCrudAppService<User, ...>
{
    protected override string UpdatePermissionName { get => base.UpdatePermissionName; [AbpAllowAnonymous] set => base.UpdatePermissionName = value; }

    public UserAppService(/*omitted for brevity*/) 
    {
        UpdatePermissionName = "Users.Update";
    }
}
0reactions
gpcaretticommented, Oct 9, 2018

@ismcagdas

If you make your CreateFilteredQuery method virtual, it will not work I guess.

CreateFilteredQuery is virtual by design as my TaskAppService is derived from Abp.Application.Services.CrudAppServiceBase<…>.

So, IMHO protected methods should not affected by the Authorize attribute of the Application Service class. Only public methods should be affected by it.

I solved the problem by overriding the default AuthorizationHelper:

    /// <summary>
    ///     Override the [AbpAuthorize] attribute for skipping protected methods.
    ///     The default [AbpAuthorize] on the class apply the attribute to both public and protected method.
    ///     This override skip protected methods
    /// </summary>
    public class MyAuthorizationHelper : AuthorizationHelper {

        public MyAuthorizationHelper(
            IFeatureChecker featureChecker,
            IAuthorizationConfiguration authConfiguration)
            : base(featureChecker, authConfiguration) {
        }

        /// <summary>
        /// Override the method for implementing the indicated logic
        /// </summary>
        public override Task AuthorizeAsync(MethodInfo methodInfo, Type type) {
            if (methodInfo.IsPublic) return base.AuthorizeAsync(methodInfo, type);

            // Gp - if methods is internal do not apply the attribute
            if (methodInfo.IsVirtual && methodInfo.IsFamily) {
                return Task.CompletedTask;
            }

            return base.AuthorizeAsync(methodInfo, type);
        }
    }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Azure App Service Problem - 500.79 Internal Server Error
1 Answer. 500.79: The request failed because of an unhandled exception in the Easy Auth module. As correctly pointed by David , follow...
Read more >
Azure AD authentication for Application Insights
The client failed to authenticate with the given credential. This error usually occurs when the credential used doesn't have the correct role ......
Read more >
Debugging App Service with Azure AD authentication issues
AAD authentication enabled from the Azure Portal without any code change. ... If not where in the Azure App Service runtime it failed....
Read more >
Service | Android Developers
Quickly bring your app to life with less code, using a modern declarative approach to UI, and the simplicity of Kotlin. ... Start...
Read more >
Authorization failed for Azure App service deploy task
After adding the Azure App Service Deploy task in build definition, when we select the subscription and try to Authorize it, we get...
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