T.Williams
T.Williams

Reputation: 31

ServiceStack API service RequiresAnyRole always returns 403 error

I've looked at several examples of ServiceStack's Authentication/Authorization code but I can't seem to get past this issue.

I have created a custom AuthFeature which derives from BasicAuthProvider and registered it in the plugins on my AppHost. In my custom provider I overrode TryAuthenticate and OnAuthenticated and on my service I have decorated the class with attributes for [Authenticate] and [RequiresAnyRole("Test")]. In my use case, I pass a username and password in my Auth header hitting my service, which calls TryAuthenticate (and passes authentication), then hits the OnAuthenticated method which I fill the session variable with a role (in this case "Test"). The result is a 403 Invalid Role. If I remove the RequiresAnyRole attribute the authentication works, and I can even look at the current session variable and see my role that I created. Additionally I have tried RequiredRole and RequiredPermission (by adding a permission to the session as well) with the same result.

Can someone tell me if I am properly adding the session with my test role correctly, or if I have implemented the custom auth provider correctly?

My auth provider code:

public class AdAuthProvider : BasicAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        var authenticated = false;
        UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), userName);
        var adRealm = System.Configuration.ConfigurationManager.AppSettings["ADRealm"];
        if (userPrincipal != null)
        {
            using (var pc = new PrincipalContext(ContextType.Domain, adRealm))
            {
                authenticated = pc.ValidateCredentials(userName, password);
            }                
        }
        return authenticated;
    }


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

        session.Roles = new List<string>();                
        session.Roles.Add("Test");         

        authService.SaveSession(session, new System.TimeSpan(0, 30, 0));
        return null;

    }

My service code:

[Authenticate]
[RequiresAnyRole("Test")]
public class TestService: Service
{
  ...

Upvotes: 3

Views: 293

Answers (1)

Darren Reid
Darren Reid

Reputation: 2322

You'll need to use use the AuthRepository to AssignRole rather than using the session object which doesn't persist.

Have a look at the assignrole service code on GitHub to see how to resolve your authRepo and assign the role.

var authRepo = HostContext.AppHost.GetAuthRepository(base.Request);
using (authRepo as IDisposable)
{
    var userAuth = authRepo.GetUserAuthByUserName(request.UserName);
    if (userAuth == null)
        throw HttpError.NotFound(request.UserName);

    authRepo.AssignRoles(userAuth, request.Roles, request.Permissions);

https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/Auth/AssignRolesService.cs

Upvotes: 2

Related Questions