ServiceStack认证与现有数据库

本文关键字:数据库 认证 ServiceStack | 更新日期: 2023-09-27 17:52:55

我一直在看ServiceStack,我试图了解如何使用现有数据库的服务上的BasicAuthentication。我想生成一个公钥(用户名)和密钥(密码),并把它放在一个现有的用户记录。然后,用户将其与请求一起传递给ServiceStack端点。

我需要在ServiceStack堆栈中实现什么才能使其工作?

我看了IUserAuthRepository和CredentialsAuthProvider基类,看起来我应该在我现有的数据库表上实现IUserAuthRepository。

我也在试图找出我应该实现的最低限度是什么来获得身份验证工作。我不会使用该服务来添加或更新用户对该服务的访问权限,而是使用一个单独的web应用程序。

任何帮助和过去的经验都是非常感谢的。

ServiceStack认证与现有数据库

对现有数据库进行身份验证的示例(在本例中是通过Umbraco/ASP)。. NET会员系统)。1)创建您的AuthProvider(请原谅冗长的代码,并注意您不必重写TryAuthenticate,这是为了检查用户是否是特定Umbraco应用程序别名的成员):

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Security;
using ServiceStack.Configuration;
using ServiceStack.Logging;
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceInterface.Auth;
using ServiceStack.WebHost.Endpoints;
using umbraco.BusinessLogic;
using umbraco.providers;
public class UmbracoAuthProvider : CredentialsAuthProvider
{
    public UmbracoAuthProvider(IResourceManager appSettings)
    {
        this.Provider = "umbraco";
    }
    private UmbracoAuthConfig AuthConfig
    {
        get
        {
            return EndpointHost.AppHost.TryResolve<UmbracoAuthConfig>();
        }
    }
    public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
    {
        ILog log = LogManager.GetLogger(this.GetType());
        var membershipProvider = (UsersMembershipProvider)Membership.Providers["UsersMembershipProvider"];
        if (membershipProvider == null)
        {
            log.Error("UmbracoAuthProvider.OnAuthenticated - NullReferenceException - UsersMembershipProvider");
            session.IsAuthenticated = false;
            return;
        }
        MembershipUser user = membershipProvider.GetUser(session.UserAuthName, false);
        if (user == null)
        {
            log.ErrorFormat(
                "UmbracoAuthProvider.OnAuthenticated - GetMembershipUser failed - {0}", session.UserAuthName);
            session.IsAuthenticated = false;
            return;
        }
        if (user.ProviderUserKey == null)
        {
            log.ErrorFormat(
                "UmbracoAuthProvider.OnAuthenticated - ProviderUserKey failed - {0}", session.UserAuthName);
            session.IsAuthenticated = false;
            return;
        }
        User umbracoUser = User.GetUser((int)user.ProviderUserKey);
        if (umbracoUser == null || umbracoUser.Disabled)
        {
            log.WarnFormat(
                "UmbracoAuthProvider.OnAuthenticated - GetUmbracoUser failed - {0}", session.UserAuthName);
            session.IsAuthenticated = false;
            return;
        }
        session.UserAuthId = umbracoUser.Id.ToString(CultureInfo.InvariantCulture);
        session.Email = umbracoUser.Email;
        session.DisplayName = umbracoUser.Name;
        session.IsAuthenticated = true;
        session.Roles = new List<string>();
        if (umbracoUser.UserType.Name == "Administrators")
        {
            session.Roles.Add(RoleNames.Admin);
        }
        authService.SaveSession(session);
        base.OnAuthenticated(authService, session, tokens, authInfo);
    }
    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        ILog log = LogManager.GetLogger(this.GetType());
        var membershipProvider = (UsersMembershipProvider)Membership.Providers["UsersMembershipProvider"];
        if (membershipProvider == null)
        {
            log.Error("UmbracoAuthProvider.TryAuthenticate - NullReferenceException - UsersMembershipProvider");
            return false;
        }
        if (!membershipProvider.ValidateUser(userName, password))
        {
            log.WarnFormat("UmbracoAuthProvider.TryAuthenticate - ValidateUser failed - {0}", userName);
            return false;
        }
        MembershipUser user = membershipProvider.GetUser(userName, false);
        if (user == null)
        {
            log.ErrorFormat("UmbracoAuthProvider.TryAuthenticate - GetMembershipUser failed - {0}", userName);
            return false;
        }
        if (user.ProviderUserKey == null)
        {
            log.ErrorFormat("UmbracoAuthProvider.TryAuthenticate - ProviderUserKey failed - {0}", userName);
            return false;
        }
        User umbracoUser = User.GetUser((int)user.ProviderUserKey);
        if (umbracoUser == null || umbracoUser.Disabled)
        {
            log.WarnFormat("UmbracoAuthProvider.TryAuthenticate - GetUmbracoUser failed - {0}", userName);
            return false;
        }
        if (umbracoUser.UserType.Name == "Administrators"
            || umbracoUser.GetApplications()
                          .Any(app => this.AuthConfig.AllowedApplicationAliases.Any(s => s == app.alias)))
        {
            return true;
        }
        log.WarnFormat("UmbracoAuthProvider.TryAuthenticate - AllowedApplicationAliases failed - {0}", userName);
        return false;
    }
}
public class UmbracoAuthConfig
{
    public UmbracoAuthConfig(IResourceManager appSettings)
    {
        this.AllowedApplicationAliases = appSettings.GetList("UmbracoAuthConfig.AllowedApplicationAliases").ToList();
    }
    public List<string> AllowedApplicationAliases { get; private set; }
}

2)通过常用的AppHost配置方法注册提供商:

    public override void Configure(Container container)
    {
        // .... some config code omitted....
        var appSettings = new AppSettings();
        AppConfig = new AppConfig(appSettings);
        container.Register(AppConfig);
        container.Register<ICacheClient>(new MemoryCacheClient());
        container.Register<ISessionFactory>(c => new SessionFactory(c.Resolve<ICacheClient>()));
        this.Plugins.Add(
            new AuthFeature(
                // using a custom AuthUserSession here as other checks performed here, e.g. validating Google Apps domain if oAuth enabled/plugged in.
                () => new CustomAuthSession(), 
                new IAuthProvider[] { new UmbracoAuthProvider(appSettings) 
                                    }) {
                                          HtmlRedirect = "/api/login" 
                                       });
}

3)现在可以对现有的Umbraco数据库@ yourapiddomain/auth/Umbraco进行身份验证,使用Umbraco管理用户/访问API。不需要实现额外的用户密钥/秘密或BasicAuthentication,除非您真的想....

我刚刚开始使用ServiceStack,我需要完全相同的东西-我今天设法让它工作。

通过基本认证登录用户的绝对最小值是:
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceInterface.Auth;
public class CustomBasicAuthProvider : BasicAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        // here, you can get the user data from your database instead
        if (userName == "MyUser" && password == "123")
        {
            return true;
        }
        return false;
    }
}

…并将其注册到AppHost:

Plugins.Add(new AuthFeature(() => new CustomUserSession(),
    new IAuthProvider[] {
        new CustomBasicAuthProvider()
    }) { HtmlRedirect = null });

就是这样!


另一个可能的解决方案是使用默认的BasicAuthProvider,并提供自己的IUserAuthRepository实现。

如果你感兴趣的话,我也可以给你看一个例子。


编辑:

这是最小的IUserAuthRepository -只是继承InMemoryAuthRepository和覆盖TryAuthenticate:

using ServiceStack.ServiceInterface.Auth;
public class CustomAuthRepository : InMemoryAuthRepository
{
    public override bool TryAuthenticate(string userName, string password, out UserAuth userAuth)
    {
        userAuth = null;
        if (userName == "MyUser" && password == "123")
        {
            userAuth = new UserAuth();
            return true;
        }
        return false;
    }
}

…并将其注册到AppHost:

container.Register<IUserAuthRepository>(r => new CustomAuthRepository());

当然,您还需要注册一个默认的AuthProviders (Basic, Credentials,等等)