使用现有数据库的ServiceStack身份validation

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

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

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

我也在试图弄清楚我应该实现什么才能使身份validation正常工作。 我不会使用该服务来添加或更新用户对服务的访问权限,而是使用单独的Web应用程序。

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

针对现有数据库进行身份validation的示例(在本例中为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(); } } public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary 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(); 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 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(new MemoryCacheClient()); container.Register(c => new SessionFactory(c.Resolve())); this.Plugins.Add( new AuthFeature( // using a custom AuthUserSession here as other checks performed here, eg validating Google Apps domain if oAuth enabled/plugged in. () => new CustomAuthSession(), new IAuthProvider[] { new UmbracoAuthProvider(appSettings) }) { HtmlRedirect = "/api/login" }); } 

3)现在可以对现有的Umbraco数据库@ yourapidomain / auth / umbraco进行身份validation,使用Umbraco来管理用户/访问API。 除非你真的想……否则不需要实现额外的用户密钥/秘密或BasicAuthentication

我刚开始使用ServiceStack,我需要完全相同的东西 – 我今天设法让它运行起来。

通过Basic Auth登录用户的绝对最低限度是:

 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 – 只是inheritance自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(r => new CustomAuthRepository()); 

当然,您还需要注册一个默认的AuthProviders (Basic,Credentials,无论如何)。