Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceStack Custom User Authentication

Does anyone have an actual example of how to use int RefId as proposed in this question?

I am trying to get authentication going but I need to marry up the userAuth data with my own user table. The problem is I have no idea how to pass an additional parameter to the "/register" method. I guess I'm looking for an event like "OnAddUser" which will allow me to throw some additional parameters into the mix.

I managed to get the user registration working pretty quickly, it was super easy. Maybe the problem is that it was too easy? I can see it work but I can't figure out how to get between it and the database.

Either the dictionary approach or the RefId approach will probably work for me, it's just no obvious to me how use either.

Is it possible to override the create user altogether? I found this code:

MyServices.cs

which looks like it's doing the create user in place of "/register" but there are some other articles that suggest that you can't override the ServiceStack DTOs, you have to use the default tables.

like image 776
user2033791 Avatar asked Oct 19 '22 08:10

user2033791


1 Answers

You could include your own Register Service by using a copy of the RegisterService source code and modify it to suit your needs, e.g. Use a custom Register DTO with the additional properties you want.

But you can easily pass additional params without changing the existing Register DTO by adding it to the ?querystring which you can access inside your Services with:

var myParam = base.Request.QueryString["myParam"];

Otherwise the way to add your Custom Logic during registration or Authentication is to tap into the existing Session or Auth Events.

TechStacks has an example of this in its CustomAuthUserSession:

public class CustomUserSession : AuthUserSession
{
    public string DefaultProfileUrl { get; set; }

    public string GithubProfileUrl { get; set; }
    public string TwitterProfileUrl { get; set; }

    public override void OnAuthenticated(IServiceBase authService, 
        IAuthSession session, 
        IAuthTokens tokens, 
        Dictionary<string, string> authInfo)
    {
        base.OnAuthenticated(authService, session, tokens, authInfo);
        var appSettings = authService.TryResolve<IAppSettings>();
        var userAuthRepo = authService.TryResolve<IAuthRepository>();
        var userAuth = userAuthRepo.GetUserAuth(session, tokens);
        var dbConnectionFactory = authService.TryResolve<IDbConnectionFactory>();
        foreach (var authTokens in session.ProviderOAuthAccess)
        {
            if (authTokens.Provider.ToLower() == "github")
            {
                GithubProfileUrl = session.GetProfileUrl();
            }
            if (authTokens.Provider.ToLower() == "twitter")
            {
                TwitterProfileUrl = session.GetProfileUrl();
                if (appSettings.GetList("TwitterAdmins").Contains(session.UserName) 
                    && !session.HasRole(RoleNames.Admin))
                {
                    userAuthRepo.AssignRoles(userAuth, roles:new[]{RoleNames.Admin});
                }
            }

            DefaultProfileUrl = GithubProfileUrl ?? TwitterProfileUrl;
            using (var db = dbConnectionFactory.OpenDbConnection())
            {
                var userAuthInstance = db.Single<CustomUserAuth>(x => 
                    x.Id == this.UserAuthId.ToInt());
                if (userAuthInstance != null)
                {
                    userAuthInstance.DefaultProfileUrl = this.DefaultProfileUrl;
                    db.Save(userAuthInstance);
                }
            }
        }
    }
}

Which fetches the Profile Url of the User when they login via GitHub or Twitter. Will assign the Admin role to users in the TwitterAdmins AppSetting, which is a way to assign admin rights to known Twitter users. Finally the retrieved Profile Url is added to the CustomUserAuth POCO Table and saved.

TechStacks tells ServiceStack to use its own CustomUserAuth table instead by registering a generic OrmLiteAuthRepository:

var authRepo = new OrmLiteAuthRepository<CustomUserAuth, UserAuthDetails>(dbFactory);
container.Register<IUserAuthRepository>(authRepo);
authRepo.InitSchema();

Where it will now Save User Information in the CustomUserAuth instead of the default UserAuth table.

like image 179
mythz Avatar answered Oct 21 '22 06:10

mythz