5

How would I implement the following scenario using ServiceStack?

Initial request goes to http://localhost/auth having an Authorization header defined like this:

Authorization: Basic skdjflsdkfj=

The IAuthProvider implementation validates against a user store and returns a session token as a response body (JSON).

The client uses this token an resends it against the subsequent requests like http://localhost/json/reply/orders using the Authorization header like this:

Authorization: BasicToken <TokenFromPreviousSuccessfulLogin>

Using a AuthenticateAttribute I want to flag my Service to use Authentication.

How should I implement the validation of the token for the subsequent requests? How should I implement the IAuthProvider to provide the token? How would I register the Providers etc.? Using RequestFilters or using the AuthFeature?

Alexander Zeitler
  • 11,919
  • 11
  • 81
  • 124

1 Answers1

7

ServiceStack's JWT AuthProvider and API Key AuthProvider both use token based Authentication.

Otherwise the BasicAuth Provider is a very simple class that simply extracts the UserName and Password from the BasicAuth Header and evaluates it:

public override object Authenticate(...)
{
    var httpReq = authService.RequestContext.Get<IHttpRequest>();
    var basicAuth = httpReq.GetBasicAuthUserAndPassword();
    if (basicAuth == null)
        throw HttpError.Unauthorized("Invalid BasicAuth credentials");

    var userName = basicAuth.Value.Key;
    var password = basicAuth.Value.Value;

    return Authenticate(authService, session, userName, password, request.Continue);
}

If you want to provide enhanced behavior, I would simply inherit this class check for the Authorization: BasicToken header, if it exists use that otherwise call the base.Authenticate(...) method to perform the initial validation.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • Thanks for your reply. The question was geared towards the scenarios described [here](http://stackoverflow.com/questions/16690758/alternative-to-cookie-based-session-authentication). – Alexander Zeitler May 29 '13 at 06:24
  • @mythz I have been trying to do exactly this, but you can't set the provider name or realm on the base class, because the BasicAuthProvider doesn't let you set them in the constructor. – Rebecca Oct 07 '15 at 10:29
  • @Junto what do you mean by it [doesn't let you set them in the constructor](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/Auth/BasicAuthProvider.cs#L14)? – mythz Oct 07 '15 at 10:45
  • If I inherit from BasicAuthProvider, the constructor `public BasicAuthProvider(IAppSettings appSettings) : base(appSettings, Realm, Name) {}` [has no realm or name parameter](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/Auth/BasicAuthProvider.cs#L18) to override the base setting of "/auth/basic" and "basic". Hence, I can't do this: `public MyCustomAuthProvider(IResourceManager appSettings) : base(appSettings, "/auth/mycustomauth", "mycustomauth")`. – Rebecca Oct 07 '15 at 12:37
  • @mythz I got around it by inheriting from the `CredentialsAuthProvider` instead btw. Not that I need to pass in any credentials as part of the request, but it seems to work anyway. – Rebecca Oct 07 '15 at 12:38
  • @Junto I'm not seeing the issue, `Provider` and `AuthRealm` are public properties, just set them in your own constructor? – mythz Oct 07 '15 at 12:40
  • @mythz excuse me whilst I go back under my rock and hide! Now I feel stupid. Thanks for the help :-) – Rebecca Oct 07 '15 at 13:10