我已经实现了自定义身份验证提供程序(CredentialsAuthProvider)来验证自己。这里的一切都很完美。我通过ASP.NET客户端应用程序中的以下代码进行身份验证。
var res = Client.Post(new Authenticate
{
provider = CredentialsAuthProvider.Name,
UserName = "admin",
Password = "topsecret",
RememberMe = true
});
我的自定义CredentialsAuthProvider中的TryAuthenticate被调用,如果正确则返回true,然后调用IHttpResult OnAuthenticated
。效果很好。
在我的OnAuthenticated
方法中,我然后设置会话的某些属性的值。所以我做了这样的事情:
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
try
{
// Save the browser cookie.
if (authService.Request is IHttpResponse httpRes)
httpRes.Cookies.AddPermanentCookie(HttpHeaders.XUserAuthId, session.UserAuthId);
session.DisplayName = "MyName";
session.IsAuthenticated = true;
// Save the user session object (ServiceStack stores it in the in-memory cache).
authService.SaveSession(session, TimeSpan.FromHours(5));
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
catch (Exception ex)
{
return new HttpResult(HttpStatusCode.ExpectationFailed);
}
}
此外,直到现在一切都很完美。
现在,如果我想访问需要身份验证的DTO(在我的示例中为Products
),我仍然会获得Unauthorized
。即使我刚认证并保存了我的会话。
var response = Client.Get(new GetProducts());
我可以看到我的自定义AuthUserSession中的方法IsAuthorized
被调用,但查看基本属性(AuthUserSession),我可以看到我之前分配的属性(DisplayName,IsAuthorized) )仍有默认值。
问题:为什么我在OnAuthenticated
中分配的属性未被保存?
非常感谢!
编辑:我意识到当我使用它时:
using (JsonServiceClient disposableClient = new JsonServiceClient("http://localhost:24131"))
{
var res = disposableClient.Post(new Authenticate
{
provider = CredentialsAuthProvider.Name,
UserName = "admin",
Password = "topsecret",
RememberMe = true
});
var response = disposableClient.Get(new GetProducts());
}
而不是将我的JsonServiceClient用作私有类成员,它可以工作。但我不想每次尝试访问资源时都要进行身份验证。这种行为的原因是什么?
答案 0 :(得分:2)
大多数自定义AuthProvider都是不必要的,并且已由OnAuthenticated()
添加,HttpHeaders.XUserAuthId
添加IsAuthenticated=true
Cookie,设置public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
session.DisplayName = "MyName";
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
并保存会覆盖现有的会话,所以基本上是您的自定义Impl应该简化为:
OnSaveSession()
如果你想改变会话的持续时间,你可以覆盖AppHost中的public override void OnSaveSession(IRequest httpReq,IAuthSession session,TimeSpan? expiresIn=null)
=> base.OnSaveSession(httpReq, session, TimeSpan.FromHours(5));
,只要会话被保存在ServiceStack的任何地方,就会被调用:
Dispose()
此外,您不必JsonServiceClient
var client = new JsonServiceClient("http://localhost:24131");
var response = client.Post(new Authenticate
{
//Client libs usually don't have access to CredentialsAuthProvider
provider = "credentials",
UserName = "admin",
Password = "topsecret",
RememberMe = true
});
has no effect。所以你的客户端代码就是:
var response = client.Get(new GetProducts());
使用ServiceClient进行身份验证会在客户端实例上填充Session Cookies,然后您就可以使用该stored in the registered ICacheClient进行经过身份验证的请求:
urn:iauthsession:{sessionId}
请注意,会话为distributed caching provider,因此,如果您的App域重新启动,则会丢失所有会话。要在应用重新启动时保留用户会话,您可以使用stateless Auth Provider like JWT(即除内存之外的任何缓存提供程序)或使用API Key Auth Provider或Session Cookies are being sent。
如果您收到UnAuthenticated Response并且您的应用程序尚未重新启动(清除存储在内存缓存中的所有会话),请使用像Fiddler或WireShark这样的数据包/ http嗅探器查看原始HTTP Headers以检查相同的still exists in the cache和经过身份验证的用户会话create your own iterator位于:
{sessionId}
ss-pid
是.paragraphs
Cookie的值。