Yash
Yash

Reputation: 11

ServiceStack Basic Authentication Failure

I'm trying to utilize the basic authentication of ServiceStack but even after passing the correct credentials, I'm getting the error:

[Authenticate: 6/16/2014 4:00:22 AM]: [REQUEST: {UserName:john,Password:test}] 
ServiceStack.HttpError: Invalid BasicAuth credentials at 
ServiceStack.Auth.BasicAuthProvider.Authenticate(IServiceBase authService, IAuthSession 
session, Authenticate request) at 
ServiceStack.Auth.AuthenticateService.Authenticate(Authenticate request, String provider, 
IAuthSession session, IAuthProvider oAuthConfig) at 
ServiceStack.Auth.AuthenticateService.Post(Authenticate request) at 
ServiceStack.Auth.AuthenticateService.Get(Authenticate request) at lambda_method(Closure , 
Object , Object ) at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object 
instance, TRequest requestDto)

The lines of code in my AppHost.cs class Configure function is as follows:

// Register AuthFeature with custom user session and Basic auth provider
Plugins.Add(new AuthFeature(
() => new AuthUserSession(),
new AuthProvider[] { new BasicAuthProvider() }
));

Plugins.Add(new RegistrationFeature());

// register storage for user sessions 
container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<ISessionFactory>(c => new SessionFactory(c.Resolve<ICacheClient>()));

var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRep);

//Add a user for testing purposes
string hash;
string salt;
new SaltedHash().GetHashAndSaltString("test", out hash, out salt);
userRep.CreateUserAuth(new UserAuth
{
    Id = 1,
    DisplayName = "DisplayName",
    Email = "[email protected]",
    UserName = "john",
    FirstName = "FirstName",
    LastName = "LastName",
    PasswordHash = hash,
    Salt = salt,
}, "test");

And the URL that I'm utilizing for authentication is:

http://<domain>:63743/auth?Username=john&Password=test

Please let me know what can be the root cause of this behavior?

Upvotes: 1

Views: 857

Answers (1)

mythz
mythz

Reputation: 143389

It doesn't look like you're using Basic Auth correctly, BasicAuthProvider in ServiceStack means HTTP Basic Auth: (i.e. it doesn't mean Simple Auth).

There is BasicAuth support enabled in our ServiceClients, some examples of this is in AuthTests.cs:

The way you send HTTP Basic Auth is using the Authorization HTTP header, e.g:

Authorization: basic {bas64encoded user:pass}

Here's example of sending HTTP Basic Auth with a WebRequest:

var base64Token = Convert.ToBase64String(
    Encoding.UTF8.GetBytes(AllowedUser + ":" + AllowedPass));
var req = (HttpWebRequest)WebRequest.Create("http://domain.com/secure");
req.Headers["Authorization"] = "basic " + base64Token;

If you want to login via a url then you want to register a CredentialsAuthProvider, i.e:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new AuthProvider[] { new CredentialsAuthProvider() }
));

Which will let you login at the url:

/auth/credentials?Username=john&Password=test

Creating your own Custom Credentials Provider

If you prefer, you can provide your own Custom Auth Provider you can inherit from CredentialsAuthProvider and override TryAuthenticate with your own custom implementation, e.g:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, 
        string userName, string password)
    {
        return userName == "john" && password == "test";
    }
}

Which you can then register with:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new AuthProvider[] { 
        new CustomCredentialsAuthProvider(),
    }
));

Upvotes: 1

Related Questions