如何在 AuthUserSession 中存储 PreRequestFilter 信息
How to store PreRequestFilter information in AuthUserSession
我正在使用 ServiceStack 构建 Web 服务,它必须支持多个供应商。 Web 服务为所有供应商提供基本相同的功能,但有一些例外。
为了尽可能多地重复使用功能,我提出了以下 URL 方案:
http://localhost/brand1/templates
http://localhost/brand2/templates
"brand1" 和 "brand2" 不是服务,但 "templates" 是。模板服务的请求 DTO 将有一个名为 "Brand" 的 属性,如下所示:
[Route("/{Brand}/templates", "GET")]
public class GetTemplates
{
public Brand Brand { get; set; }
}
所以在模板服务中我知道我在处理哪个品牌。这个方案效果不错。
我想不通的是这个。服务的用户必须经过身份验证,我无法弄清楚在用户经过身份验证后如何处理服务的重定向,因为我必须传递品牌信息。我创建了自己的 CustomAuthProvider class 继承了 CredentialsAuthProvider。在 TryAuthenticate 方法中,如果我知道它是什么,我可以将 authService.GetSession().ReferrerUrl 属性 设置为正确的品牌。
到目前为止,我发现获取此信息的唯一方法是注册 PreRequestFilter。我的想法是,由于 URL(例如 http://localhost/brand1/templates)包含我可以将其存储在我自己的 AuthUserSession class 中的品牌。我不知道该怎么做。我有一个传递给 AuthFeature 构造函数的 "SessionFactory" 方法。但是我应该在那里做什么?我如何获得我在 PreRequestFilter 中获得的品牌?将它存储在 AppHost 的字段中是否安全?我认为不是因为并发问题。如何将 PreRequestFilter 绑定到 SessionFactory 方法?
我希望我已经足够清楚地解释我的问题了吗?
您可以将 Url 设置为在 ServiceStack Authentication 期间重定向到的不同位置,按优先顺序排列如下:
Session.ReferrerUrl
Url 如果已填充
- 向
/auth
发出请求时 Continue QueryString、FormData 参数(即 Authenticate.Continue 属性)
- HTTP Referer HTTP Header
- 当前
AuthProvider
使用的回调Url
我对解决方案想得太多了,因为我没有意识到我在 CredentialsAuthProvider 的 TryAuthenticate 方法的 IServiceBase 参数中拥有我需要的所有信息 class。
最后我得出以下解决方案:
public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService,
string userName, string password)
{
var session = authService.GetSession();
var origQuery = authService.Request.UrlReferrer.Query;
session.ReferrerUrl = "/error";
var queryString = origQuery.Substring(10); // strip "redirect="
var decodedUrl = HttpUtility.UrlDecode(queryString);
if (!string.IsNullOrWhiteSpace(decodedUrl))
{
var query = new Uri(decodedUrl);
session.ReferrerUrl = query.AbsolutePath;
}
return DoAuthentication(userName, password);
}
}
我正在使用 ServiceStack 构建 Web 服务,它必须支持多个供应商。 Web 服务为所有供应商提供基本相同的功能,但有一些例外。
为了尽可能多地重复使用功能,我提出了以下 URL 方案:
http://localhost/brand1/templates
http://localhost/brand2/templates
"brand1" 和 "brand2" 不是服务,但 "templates" 是。模板服务的请求 DTO 将有一个名为 "Brand" 的 属性,如下所示:
[Route("/{Brand}/templates", "GET")]
public class GetTemplates
{
public Brand Brand { get; set; }
}
所以在模板服务中我知道我在处理哪个品牌。这个方案效果不错。
我想不通的是这个。服务的用户必须经过身份验证,我无法弄清楚在用户经过身份验证后如何处理服务的重定向,因为我必须传递品牌信息。我创建了自己的 CustomAuthProvider class 继承了 CredentialsAuthProvider。在 TryAuthenticate 方法中,如果我知道它是什么,我可以将 authService.GetSession().ReferrerUrl 属性 设置为正确的品牌。
到目前为止,我发现获取此信息的唯一方法是注册 PreRequestFilter。我的想法是,由于 URL(例如 http://localhost/brand1/templates)包含我可以将其存储在我自己的 AuthUserSession class 中的品牌。我不知道该怎么做。我有一个传递给 AuthFeature 构造函数的 "SessionFactory" 方法。但是我应该在那里做什么?我如何获得我在 PreRequestFilter 中获得的品牌?将它存储在 AppHost 的字段中是否安全?我认为不是因为并发问题。如何将 PreRequestFilter 绑定到 SessionFactory 方法?
我希望我已经足够清楚地解释我的问题了吗?
您可以将 Url 设置为在 ServiceStack Authentication 期间重定向到的不同位置,按优先顺序排列如下:
Session.ReferrerUrl
Url 如果已填充- 向
/auth
发出请求时 Continue QueryString、FormData 参数(即 Authenticate.Continue 属性) - HTTP Referer HTTP Header
- 当前
AuthProvider
使用的回调Url
我对解决方案想得太多了,因为我没有意识到我在 CredentialsAuthProvider 的 TryAuthenticate 方法的 IServiceBase 参数中拥有我需要的所有信息 class。
最后我得出以下解决方案:
public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService,
string userName, string password)
{
var session = authService.GetSession();
var origQuery = authService.Request.UrlReferrer.Query;
session.ReferrerUrl = "/error";
var queryString = origQuery.Substring(10); // strip "redirect="
var decodedUrl = HttpUtility.UrlDecode(queryString);
if (!string.IsNullOrWhiteSpace(decodedUrl))
{
var query = new Uri(decodedUrl);
session.ReferrerUrl = query.AbsolutePath;
}
return DoAuthentication(userName, password);
}
}