cnanda
cnanda

Reputation: 33

ServiceStack Authorization - Access Route Information

In the documentation for ServiceStack, it says that the best practice is:

Normally ServiceStack calls the method bool HasPermission(string permission) in IAuthSession. This method checks if the list List Permissions in IAuthSession contains the required permission.

IAuthSession is stored in a cache client as explained above You can fill this list in the method OnAuthenticated you've overriden in the first part of this tutorial.

I am integrating with an existing system, and have my custom BasicAuthProvider working (inherited from the base BasicAuthProvider). Authentication is working perfectly, now I am building out the Authorization portion. I plan on using the Permissions list as listed above, but I need access to the Route information to determine if a user has access to a particular resource. I see in the IAuthServiceBase there is an IRequestContext which has the absolute URL, but before going through and parsing that out, I figured there has to be a way to gain access to the ServiceStack Route structure to give me either the class name of the Service being requested, or the DTO the requested service is related to.

Here is the OnAuthenticated method from my BasicAuthProvider class:

public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
    {


        UserSession sess = (UserSession)session;

        Model.User currentUser = UserRepository.GetUserByUsername(session.UserAuthName);

        //Fill the IAuthSession with data which you want to retrieve in the app eg:
        session.FirstName = currentUser.Person.FirstName;
        session.LastName = currentUser.Person.LastName;
        session.UserName = currentUser.User1;
        sess.CurrentUser = currentUser;
        //Important: You need to save the session!
        authService.SaveSession(session, TimeSpan.FromDays(1));
    }

Under MVC I have used some of the Raw Request Data to get the Controller and Action name before, to determine resource authorization, but this is the first project I am using ServiceStack with.

Upvotes: 3

Views: 2045

Answers (1)

mythz
mythz

Reputation: 143319

You may find the [RequiredPermission] attribute or even the implementation of it will help you, e.g. the 3rd parameter passed in a RequestFilter is the Request DTO.

And since a Request DTO maps 1:1 with the service, you can be sure that the request is destined for the IService<TRequest> (or its subclasses e.g. ServiceBase<T>, RestServiceBase<T>). You can access the type of the service programatically as done in the FilterAttributeCache:

var serviceType = EndpointHost.Metadata.GetServiceTypeByRequest(requestDtoType);

I'm not sure of the exact context/use-case you're trying to support but using the [RequiredPermission] or [RequiredRole] attributes may have what you need which by default validates against the list of roles and permissions available in the built-in UserAuth table.

Externally you can use the /assignroles and /unassignroles web services (as part of the AuthorizationFeature plugin) to assign roles and permissions to users (it requires a user with the Admin role by default).

For more info see the documentation pages on Authentication/Authorization and Validation on the ServiceStack GitHub project wiki.

Upvotes: 2

Related Questions