【发布时间】:2014-01-08 13:19:29
【问题描述】:
我已经为我的身份验证实现了一个自定义CredentialsAuthProvider,并将其与内存会话存储中的默认值一起使用。
现在我尝试将会话存储更改为 Redis,并将其添加到 AppHost 中的 Configure() 方法中:
container.Register<IRedisClientsManager>(c =>
new PooledRedisClientManager("localhost:6379"));
container.Register<ICacheClient>(c => (ICacheClient)c
.Resolve<IRedisClientsManager>()
.GetCacheClient()).ReusedWithin(Funq.ReuseScope.None);
现在,当我进行身份验证时,我可以看到带有 urn:iauthsession:... 的密钥已添加到我的 Redis 服务器。但是所有带有[Authenticate] 属性的路由都会给出401 Unauthorized 错误。
CustomCredentialsAuthProvider 是这样实现的:
public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
if (userName != string.Empty && password != string.Empty)
{
// Database call ...
var session = (CustomSession)authService.GetSession();
session.ClientId = login.ClientId;
// Fill session...
authService.SaveSession(session, SessionExpiry);
return true;
}
return false;
}
}
ServiceStack 版本:3.9.71
编辑:
我试图覆盖 CredentialsAuthProvider IsAuthorized 方法但没有成功。
但是我从AuthUserSession 继承了我的会话对象,它也有一个IsAuthorized 方法。当我从此方法返回 true 时,Redis 会话确实使用 Authenticate 属性。
public class CustomSession : AuthUserSession
{
public int ClientId { get; set; }
...
public override bool IsAuthorized(string provider)
{
return true;
}
}
【问题讨论】:
-
我认为这与您的问题无关,但您不应该在
TryAuthenticate方法中填写会话。首选做法是在OnAuthenticated方法中。 See here。从AuthenticationAttribute中的 Redis 检索会话似乎存在问题。要对此进行调试,我将从您的一个操作处理程序中删除该属性并尝试在其中添加base.Request.GetSession(),然后查看您的会话是否在您的服务中正确恢复。 -
@Scott 当我删除
[Authenticate]属性时,我可以在操作处理程序中检索会话。所以这似乎是AuthenticationAttribute中的一个错误? -
这不是一个错误,您的实现有问题。我认为您需要设置
session.UserAuthName和session.UserAuthId除非您覆盖CredentialProvidersIsAuthorized方法。 -
谢谢@Scott,但我没有让它与 CredentialsProvider 一起工作。请参阅我更新的问题。
-
只是查看您的代码。删除
public ICacheClient cache { get; set; }ICacheClient 已在您继承的Service中设置。您可以拨打base.Cache。仍在寻找其他问题。
标签: redis servicestack servicestack-bsd servicestack-auth