We have a .net 6.0 MVC web application running with ServiceStack Ormlite 6.0.2.
We have a custom AuthenticateAttribute that extends the Servicestack AuthenticateAttribute. The intention is to to use this to query a secondary set of permissions that are stored against a CustomAuthUserSession, as we have split permissions (there are too many, and they can't all be stored in the JWT token cookie):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CustomRequiredPermissionAttribute : AuthenticateAttribute
{
public List<string> RequiredPermissions { get; set; }
public CustomRequiredPermissionAttribute(ApplyTo applyTo, params string[] permissions)
{
this.RequiredPermissions = permissions.ToList();
this.ApplyTo = applyTo;
this.Priority = (int)RequestFilterPriority.RequiredPermission;
this.HtmlRedirect = "~/PermissionDenied";
}
public CustomRequiredPermissionAttribute(params string[] permissions)
: this(ApplyTo.All, permissions)
{ }
public override async Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
//Do things here
}
...
Essentially we want to use the ExecuteAsync function to check permissions against a second list, but overriding as above doesn't work. Debugging shows that the constructor is executed, but the ExecuteAsync method never is.
Changing the class above so that it extends from the RequiredPermissionAttribute with public class CustomRequiredPermissionAttribute : RequiredPermissionAttribute will result in the RequiredPermissionAttribute working as expected against the Servicestack Permissions list - but again, using an override on ExecuteAsync doesn't appear to work, it runs as if there are no changes to the RequiredPermissionAttribute.
Do our attributes need to be registered somewhere to get them to work, or are we attempting to use the wrong method with ExecuteAsync?
The attribute is used against the MVC controllers like this:
[Authenticate, CustomRequiredPermission(PermissionType.Read, PermissionEntity.Location)]
public class MyController : _BaseController
{
...
}
I tried removing the Authenticate attribute in case that was interfering, but the result was the same - the constructor for CustomRequiredPermission is hit but not `ExecuteAsync'. I also tried decorating a method instead of the class, but saw the same result again.
The reason we haven't overridden the HasAnyPermissionsAsync method is that we want to use the built-in servicestack permissions in most areas, but in the admin area we also check against the extended (admin) permissions. This way in most cases we don't need that extra database query to get the permissions and can just use the jwt permissions each time. If all else fails this may be a good back-up.
Ultimately it sounds like there's no registration process or something similar that we're missing, and it may be a case of trying to replicate the issue in a separate solution.
These are all Request Filter Attributes which should be decorated on your Service class or its methods, e.g:
In which
ExecuteAsyncwould be called, which is how all other built-in Request Filter attributes work.It's not clear what else you're doing with the attribute for
ExecuteAsyncnot to be called.Instead of creating a custom Attribute you can try using a custom session with a custom
HasAnyPermissionsAsyncimplementation:That way you can continue to use the built-in
[RequiredPermission]and[RequiresAnyPermission]attributes