1

I'm trying to design a solution where a ServiceStack server can just use an authentication cookie from ASP.NET. (In reality, it could be any cookie. It's just getting a session ID that it can lookup details using a back channel). The custom auth providers don't seem to be the right direction since they are based on credentials being sent. Instead, a GlobalRequestFilter made more sense to me. In there, I check the cookie, get the external session information, then set them to the ServiceStack session and set IsAuthenticated. This works fine in the request service as it has access to the session details that it needs. Fine so far.

The issue, is that when I decide to lock down services with the Authenticate attribute, it apparently runs the attribute prior to my filter so it always wants to redirect them to login. What is the recommended place to add my logic so it fires before the Authenticate attribute and validates properly?

Arian Kulp
  • 831
  • 8
  • 31
  • just noticed and changed from GlobalRequestFilters to PreRequestFIlters, but still no help. still doing 401 when it sees the Authenticate attribute – Arian Kulp Jul 06 '16 at 18:43
  • I think I've got it. The actual method of determining if the session satisfies the Authenticate attribute is by overriding the IsAuthorized method of the session (you'll have to make a strong-typed AuthUserSession) and returning true based on which provider is asking. `public override bool IsAuthorized(string provider) { return base.IsAuthorized(provider); }` – Arian Kulp Jul 06 '16 at 19:44

1 Answers1

2

ServiceStack's [Autenticate] attribute is for use with ServiceStack's AuthProvider model so you'll still want to use a Custom AuthProvider. You can have a look at the IAuthWithRequest Auth Providers in the last release notes for examples of creating Custom Auth Providers that aren't based on using credentials:

By implementing IAuthWithRequest interface in your AuthProvider the [Authenticate] Request Filter will call PreAuthenticate() to perform any Auth validation before validating whether the User is Authenticated or not. Here you can populate the Users Session if the User is Authenticated, e.g:

public class MyAuthProvider : AuthProvider, IAuthWithRequest
{
    public override bool IsAuthorized(IAuthSession session, IAuthTokens tokens, Authenticate request = null)
    {
        return session.IsAuthenticated;
    }

    public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
    {
        throw new NotImplementedException("Authenticate() should not be called directly");
    }

    public void PreAuthenticate(IRequest req, IResponse res)
    {
        //Do any Auth validation...

        //populate the Session in the Request to Authenticate this user
        req.Items[Keywords.Session] = new AuthUserSession { 
           UserName = ...,
           Email = ...,
           //populate other fields
           IsAuthenticated = true,
        };
    }
}

Then to register your custom Auth Provider add it to your AuthFeature plugin in AppHost.Configure(), e.g:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
  new IAuthProvider[] { 
    new MyAuthProvider (),
  }));
mythz
  • 141,670
  • 29
  • 246
  • 390
  • 1
    Thanks! I still seem to need the IsAuthorized override on the AuthUserSession that I mentioned above, but this is the rest of it. – Arian Kulp Jul 06 '16 at 22:01