servicestackservicestack-authservicestack-autoquery

ServiceStack AutoQuery and [Authenticate] Attribute


I'd like to enforce authentication on some auto querys.

[Authenticate]
public class BusinessEntitiesService : QueryDb<DataModel.dbo.BusinessEntity>
{
}

Here's my issue. The above class is in my ServiceModel project... in order to add the [Authenticate] attribute, I need to add a reference to ServiceStack.dll which I think can cause issues down the road (according to previous guidance to only reference ServiceStack.Interfaces in the ServiceModel). I can't add the above class to ServiceInterfaces because then I'd have to reference that everywhere I use the client.

I've also tried using a GlobalRequestFilter... but that appears to goof with the AdminFeature plugin:

    private bool IsAProtectedPath(string path)
    {
        return !path.StartsWith("/auth") && !path.StartsWith("/autoquery");
    }

        GlobalRequestFilters.Add((httpReq, httpResp, requestDto) =>
        {
            if(IsAProtectedPath(httpReq.PathInfo))
                new AuthenticateAttribute().Execute(httpReq, httpResp, requestDto);
        });

enter image description here

Not really sure how to best handle this.


Solution

  • In order to apply the [Authenticate] attribute to AutoQuery Services you would need to create a custom AutoQuery implementation and apply your Filter attributes on that, e.g:

    [Authenticate]
    public class MyProtectedAutoQueryServices : Service 
    {
        public IAutoQueryDb AutoQuery { get; set; }
    
        public object Any(QueryBusinessEntity query) =>
            AutoQuery.Execute(query, AutoQuery.CreateQuery(query, Request));
    
        public object Any(QueryBusinessEntity2 query) =>
            AutoQuery.Execute(query, AutoQuery.CreateQuery(query, Request));
    }
    

    An alternative is to dynamically add attributes to your AutoQuery Request DTO, but these would need to be registered before Configure() is called, either before appHost.Init() or in your AppHost constructor, e.g:

    public class AppHost : AppHostBase
    {
        public AppHost()
        {
            typeof(QueryBusinessEntity)
                .AddAttributes(new AuthenticateAttribute());
        }
    }