Adding Authentification and Authorization using x mix

I’m trying to add basic auth to my API and I went through the documentation at:

https://docs.servicestack.net/authentication-and-authorization

I used x mix auth-db mysql which added to my project:

Configure.Db.cs and
Configure.AuthRepository.cs

The connection to mysql works and using the generated code:

“MyTable” is created with 3 other tables:

appuser
userauthdetails
userauthrole

My first question is: What is supposed to be the role of “MyTable”? Is it used to stored custom information about a user etc.?

Also using the sample code generated in:

Configure.AuthRepository.cs

public void Configure(IAppHost appHost)
{
    var authRepo = appHost.Resolve<IAuthRepository>();
    authRepo.InitSchema();

    CreateUser(authRepo, "admin@email.com", "Admin User", "p@55wOrd", roles:new[]{ RoleNames.Admin });
}

// Add initial Users to the configured Auth Repository
public void CreateUser(IAuthRepository authRepo, string email, string name, string password, string[] roles)
{
    if (authRepo.GetUserAuthByUserName(email) == null)
    {
        var newAdmin = new AppUser { Email = email, DisplayName = name };
        var user = authRepo.CreateUserAuth(newAdmin, password);
        authRepo.AssignRoles(user, roles);
    }
}

Doesn’t seem to create a username in the table appuser and the Roles column is empty?

Is this the expected behaviour for the code above? I would have expected:

authRepo.AssignRoles(user, roles);

To create the roles…?

Am I missing a step somewhere…?

Of course, trying to authenticate using the JsonServiceClient returns Unauthorized:

var authResponse = client.Post(new Authenticate {
    UserName = "admin@email.com",
    Password = "p@55w0rd",
    RememberMe = true,
});

Here is also my AppHost in case it helps.

public class AppHost : AppHostBase
{
    public AppHost()
        : base("SimpleApi", typeof(CallServices).Assembly) { }

    public override void Configure(Container container)
    {
        
        Plugins.Add(new AuthFeature(() => new AuthUserSession(),
            new IAuthProvider[] { 
                new BasicAuthProvider()
            }));
        
        Plugins.Add(new RegistrationFeature());

        Feature disableFeatures = Feature.Jsv;
        SetConfig(new HostConfig {
            EnableFeatures = Feature.All.Remove(disableFeatures),
            DebugMode = false,
            WriteErrorsToResponse = false
        });
    }
}

Thanks!

No it’s just a stub example table showing where/how you can create your own DB Tables.

Which is because the OrmLiteAuthRepository is configured to persist roles into a separate table:

Where it will instead save Roles in the separate UserAuthRole table.

That’s because you don’t have CredentialsAuthProvider configured and instead only have BasicAuthProvider which only allows authentication via HTTP Basic Auth.

Change it instead to use CredentialsAuthProvider:

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

Also you need to specify the Auth provider that you want to Authenticate with, e.g:

var authResponse = client.Post(new Authenticate {
    provider = "credentials",
    UserName = "admin@email.com",
    Password = "p@55w0rd",
    RememberMe = true,
});

I made the changes (thanks!) and now I am getting an Exception: Data too long for column ‘ProfileUrl’…?

That column is currently empty in the Mysql database created.

Here is the full exception:

ServiceStack.WebServiceException: Data too long for column ‘ProfileUrl’ at row 1
at ServiceStack.ServiceClientBase.ThrowWebServiceException[TResponse](Exception ex, String requestUri) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:860
at ServiceStack.ServiceClientBase.ThrowResponseTypeException[TResponse](Object request, Exception ex, String requestUri) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:795
at ServiceStack.ServiceClientBase.HandleResponseException[TResponse](Exception ex, Object request, String requestUri, Func1 createWebRequest, Func2 getResponse, TResponse& response) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:746
at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:1329
at ServiceStack.ServiceClientBase.Post[TResponse](IReturn`1 requestDto) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:1483
at ApiConsoleTest.Program.Main(String[] args) in C:\Kalak\service-stack\ApiConsoleTest\ApiConsoleTest\Program.cs:23

That’s because the URL you’re trying to save is too large for the default MySQL VARCHAR(255).

You can change it to use LONGTEXT if you annotate it with:

public class AppUser : UserAuth
{
    [StringLength(int.MaxValue)]
    public string ProfileUrl { get; set; }
    public string LastLoginIp { get; set; }
    public DateTime? LastLoginDate { get; set; }
}

You’ll need to DROP the existing table, so it can re-create it again.

Super. That works now.

Is there some documentation on the role of each property in UserAuth and their roles?

Thanks a lot.

No, most should be self-explanatory from their name, most of which are standard User metadata attributes populated by different Auth Providers where they exist.

Since you’re using a custom AppUser model you’ll be able to add any additional properties that don’t already exist on UserAuth otherwise the different ways of extending UserAuth explain some of the custom reference metadata properties.

I’ll have a look a the stackoverflow link. Thanks!