How to catch a parameter name inside a custom attribute using an another parameter attribute?

342 Views Asked by At

I'm implementing custom access control filters in .Net Core 7. To do it I've found a very good guide which I've adapted for my needs. But one moment is unclear for me and I cannot find answers. I googled a lot and tried a lot of things, but without success.. Maybe anyone there could help me?

So, this is the article I mentioned: https://ekobit.com/blog/asp-net-core-custom-authorization-attributes/

This is how I use my custom attributes:

        [HttpGet("ForManagersOfAccount/{id}")]
        [AccountManagerFilter]
        public ActionResult SomeAction([AccountId] int id)
        {
            return Ok("Access Granted");
        }

AccountManagerFilter reads an authorized user identity and parses a list of allowed account ids for the user:

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var user = context.HttpContext.User;
            if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
            {
                context.Result = new ForbidResult();
            }
            var userData = JsonSerializer.Deserialize<PermissionsModel>(user.FindFirst(ClaimTypes.UserData).Value);
            var accountId = GetAccountIdValue(context);

            if (accountId == null)
            {
                context.Result = new ForbidResult();
            }

            if (
                userData != null && 
                    (userData.IsAdministrator || 
                        (userData.ManagerOfAccounts.Length > 0 && userData.ManagerOfAccounts.Where(x => x == accountId).Any())
                    )
                )
            {
                base.OnActionExecuting(context);
            } 
            else
            {
                context.Result = new ForbidResult();
            }
            
        }

And AccountId custom attribute is just a Parameter type attribute without any logic inside:

    [AttributeUsage(AttributeTargets.Parameter)]
    public class AccountIdAttribute: Attribute
    {
    }

According to the original arcticle, they said that this is very simple to detect this attribute in the main attribute logic. "Once we’ve marked the correct parameter in the controller method, we can find it in ApiAuthorizationFilter. And the ‘magic strings’ are gone." But I have absolutely no idea how to do that. I checked every field in the context, googled everything about AttributeTargets.Parameter, but no success. Only thig I could do, is to get Type of my controller, find the method and the try to search for the AccountId attribute, but this is wrong, and have to relation to the execution context.

1

There are 1 best solutions below

2
Tiny Wang On

I'm also confused about the parameter attribute. But in your code sample, I noticed that the [AccountId] int id comes from the URL parameter, so I'm afraid you don't need to have that attribtue parameter, you can get the value directly from the context. By the way, authorization filer is triggered before the controller, I'm afraid I misunderstood what the blog what to achieve.

enter image description here