Вопрос

We recently switched to ServiceStack for our ReSTful web services in the same solution as our MVC 4 web page server and so far we have found it easy to work with. However, our problem is we want to add Basic Authentication and every article and blog on the subject makes it look more complex and "tricky" (their words) than it should be for a tool that makes everything else so easy. We already have the "Basic xxx" string in a database that we access through a DAL pattern using Entity Framework. We could just compare the value from the "Authenticate" header to our database value but that is the crude way. We don't want to load another library (e.g., OrmLite) or create additional tables.

My question is this...given what I have already said about our implementation, is there a simple way to say "here is our stored 'Basic xxx' string" at the correct place/time? Or do we have to override IUserAuthRepository and use it inside an override of IAuthProvider? Which seems simple until you see the other implementations that are available on the web and then you get all confused.

Thank you in advance for any response! Marcus

Это было полезно?

Решение

Implementing your own Basic AuthProvider

You would just need to inherit BasicAuthProvider and override the TryAuthenticate method with your own implementation, e.g:

public class MyBasicAuthProvider : BasicAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, 
       string userName, string password)
    {
        return MyIsValidLogin(userName, password);
    }
}

Then just make it available to ServiceStack when you register the AuthFeature, e.g:

Plugins.Add(new AuthFeature(
    () => new CustomUserSession(), //Use your own typed Custom UserSession type
    new IAuthProvider[] {
      new MyBasicAuthProvider()
    });

This plugs into ServiceStack's built-in Authentication, letting you authenticate with HTTP BasicAuth and protect your services using the built-in [Authenticate] attribute.

Sending Basic Auth using the built-in ServiceClient's

ServiceStack .NET Service Clients have built-in support for Basic Auth requests by setting the UserName/Password fields, i.e:

var client = new JsonServiceClient { 
    UserName = username,
    Password = password
};

Now when challenged with an unauthenticated request will automatically re-send the request with the BasicAuth credentials. To always send the BasicAuth on each request you can set:

client.AlwaysSendBasicAuthHeader = true;

Manually validating BasicAuth using a Global Request Filter

An alternative to using ServiceStack's built-in authentication can be to use a Global Request Filter that manually extracts the BasicAuth username and password and sets a flag on the request to indicate the request has been authenticated, e.g:

this.GlobalRequestFilters.Add((req, res, dto) => {
    var userAndPass = req.GetBasicAuthUserAndPassword();
    if (userAndPass == null)
        return;

    var username = userAndPass.Value.Key;
    var password = userAndPass.Value.Value;

    if (MyIsValidLogin(username, password)) {
        //Set a flag that will be available for the entire request:
        req.Items["UserAuthenticatedWithBasicAuth"] = username;  
    }
});

Now all services, attribute filters and any other custom logic in ServiceStack's Request pipeline can check this flag to see if it was set, e.g:

public class MyServices : Service
{
    public object Any(Request request)
    {
        var authenticatedUser = Request.Items["UserAuthenticatedWithBasicAuth"];
        if (authenticatedUser != null) {
            //this user was authenticated with BasicAuth
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top