2

现在,我们正在通过以下方式验证我们的用户:

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 Keys。我们希望将 API 密钥存储在 SQL Server 中,以避免进程停止/重新启动时出现问题。因此,客户端将使用域凭据进行身份验证,然后为后续调用生成一个 API 密钥,该密钥将存储在数据库中(理想情况下,只需使用表 servicestack 可以创建(dbo.ApiKey)。

如果我们要根据文档进行设置:

container.Register<IAuthRepository>(c => new OrmLiteAuthRepository(dbFactory));

我们在上面的函数中得到一个错误OnAuthenticated,告诉我们应该调用Init()......就像它试图创建用户表一样。所以我不确定如何允许数据库存储 API 密钥,以及依赖于活动目录以及我们为用户和角色的自定义表的自定义身份验证。

与其从 CredentialsAuthProvider 继承,不如注册一个自定义IUserAuthRepositoryIManageRoles

4

1 回答 1

2

API Key AuthProvider需要在您的 AuthFeature 中注册,例如:

Plugins.Add(new AuthFeature(...,
    new IAuthProvider[] {
        new ApiKeyAuthProvider(AppSettings),
        new WindowsAuthProvider(AppSettings),
        //...
    }));

这需要IAuthRepository你正在做的事情:

container.Register<IAuthRepository>(c => 
    new OrmLiteAuthRepository(dbFactory));

任何需要创建后端表或其他模式的 AuthProvider 都需要在 Startup 上初始化其模式,您可以这样做:

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;
    }
}
于 2016-08-11T14:56:18.983 回答