ServiceStack 自定义凭据使用数据库存储的 Api 密钥进行身份验证
ServiceStack Custom Credentials Auth with DB Stored Api Keys
现在,我们正在用这个来验证我们的用户:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
}
在使用 JsonServiceClient 时效果很好。
我们有一些用 Visual FoxPro 编写的遗留代码,它们想要调用 ServiceStack 中的一些经过身份验证的函数...为了适应这一点,我们还希望允许 Api 键。我们希望 API 密钥存储在 SQL 服务器中,以避免进程停止/重新启动时出现问题。因此,客户端将使用域凭据进行身份验证,然后为后续调用生成一个 API 密钥,该密钥将存储在数据库中(理想情况下只需使用 table 服务堆栈即可创建 (dbo.ApiKey)。
如果我们按照文档进行设置:
container.Register<IAuthRepository>(c => new OrmLiteAuthRepository(dbFactory));
上面的 OnAuthenticated
函数出现错误,告诉我们应该调用 Init()
... 就像它还试图创建用户 table 一样。因此,我不确定如何允许数据库存储 API 密钥,以及依赖于活动目录以及我们针对用户和角色的自定义 table 的自定义身份验证。
与其继承自 CredentialsAuthProvider,不如注册自定义 IUserAuthRepository
和 IManageRoles
?
需要在您的 AuthFeature 中注册 API Key AuthProvider,例如:
Plugins.Add(new AuthFeature(...,
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings),
new WindowsAuthProvider(AppSettings),
//...
}));
这需要 IAuthRepository
就像你正在做的那样:
container.Register<IAuthRepository>(c =>
new OrmLiteAuthRepository(dbFactory));
任何需要创建后端表或其他模式的 AuthProvider 都需要在启动时初始化其模式,您可以这样做:
container.Resolve<IAuthRepository>().InitSchema();
始终调用 InitSchema()
是安全的,因为它只会创建缺失的表,或者对于不需要创建模式的 AuthRepositories 会被忽略。
您 运行 遇到的一个问题是您注册了一个 IAuthRepository
并继承了一个您不想在其中使用的 CredentialsAuthProvider
,因此您可以'调用 CredentialsAuthProvider.OnAuthenticated() 因为它会将用户身份验证信息保存到存储库(如果存在)。
因此您需要提供自定义实现而不调用 base.OnAuthenticated()
,例如:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
try
{
session.IsAuthenticated = true;
session.OnAuthenticated(authService, session, tokens, authInfo);
AuthEvents.OnAuthenticated(authService.Request, session, authService, tokens, authInfo);
}
finally
{
this.SaveSession(authService, session, SessionExpiry);
}
return null;
}
}
现在,我们正在用这个来验证我们的用户:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
}
在使用 JsonServiceClient 时效果很好。
我们有一些用 Visual FoxPro 编写的遗留代码,它们想要调用 ServiceStack 中的一些经过身份验证的函数...为了适应这一点,我们还希望允许 Api 键。我们希望 API 密钥存储在 SQL 服务器中,以避免进程停止/重新启动时出现问题。因此,客户端将使用域凭据进行身份验证,然后为后续调用生成一个 API 密钥,该密钥将存储在数据库中(理想情况下只需使用 table 服务堆栈即可创建 (dbo.ApiKey)。
如果我们按照文档进行设置:
container.Register<IAuthRepository>(c => new OrmLiteAuthRepository(dbFactory));
上面的 OnAuthenticated
函数出现错误,告诉我们应该调用 Init()
... 就像它还试图创建用户 table 一样。因此,我不确定如何允许数据库存储 API 密钥,以及依赖于活动目录以及我们针对用户和角色的自定义 table 的自定义身份验证。
与其继承自 CredentialsAuthProvider,不如注册自定义 IUserAuthRepository
和 IManageRoles
?
需要在您的 AuthFeature 中注册 API Key AuthProvider,例如:
Plugins.Add(new AuthFeature(...,
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings),
new WindowsAuthProvider(AppSettings),
//...
}));
这需要 IAuthRepository
就像你正在做的那样:
container.Register<IAuthRepository>(c =>
new OrmLiteAuthRepository(dbFactory));
任何需要创建后端表或其他模式的 AuthProvider 都需要在启动时初始化其模式,您可以这样做:
container.Resolve<IAuthRepository>().InitSchema();
始终调用 InitSchema()
是安全的,因为它只会创建缺失的表,或者对于不需要创建模式的 AuthRepositories 会被忽略。
您 运行 遇到的一个问题是您注册了一个 IAuthRepository
并继承了一个您不想在其中使用的 CredentialsAuthProvider
,因此您可以'调用 CredentialsAuthProvider.OnAuthenticated() 因为它会将用户身份验证信息保存到存储库(如果存在)。
因此您需要提供自定义实现而不调用 base.OnAuthenticated()
,例如:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
try
{
session.IsAuthenticated = true;
session.OnAuthenticated(authService, session, tokens, authInfo);
AuthEvents.OnAuthenticated(authService.Request, session, authService, tokens, authInfo);
}
finally
{
this.SaveSession(authService, session, SessionExpiry);
}
return null;
}
}