我正在使用ServiceStack构建一个Web服务,它必须支持多个供应商。 Web服务为所有供应商提供了大致相同的功能,但有一些例外。
为了尽可能多地重用功能,我提出了以下网址方案:
http://localhost/brand1/templates
http://localhost/brand2/templates
“brand1”和“brand2”不是服务,而是“模板”。模板服务的请求DTO将有一个名为“Brand”的属性,如下所示:
[Route("/{Brand}/templates", "GET")]
public class GetTemplates
{
public Brand Brand { get; set; }
}
所以在模板服务中我知道我正在处理哪个品牌。这个方案运作良好。
虽然这是我无法弄清楚的。必须对服务的用户进行身份验证,并且在用户通过身份验证后我无法弄清楚如何处理服务的重定向,因为我必须传递品牌信息。我创建了自己的CustomAuthProvider类,它继承了CredentialsAuthProvider。在TryAuthenticate方法中,如果我知道它是什么,我可以将authService.GetSession()。ReferrerUrl属性设置为正确的品牌。
到目前为止,我发现获取此信息的唯一方法是注册PreRequestFilter。我的想法是,由于URL(例如http://localhost/brand1/templates)包含品牌,我可以将其存储在我自己的AuthUserSession类中。我无法弄清楚如何做到这一点。我有一个“SessionFactory”方法,我传递给AuthFeature构造函数。但是我应该在那里做什么?我如何获得我在PreRequestFilter中获得的品牌?将它存储在AppHost的字段中是否安全?我认为不是因为并发问题。如何将PreRequestFilter绑定到SessionFactory方法?
我希望我能够清楚地解释我的问题吗?
答案 0 :(得分:1)
我过度思考解决方案,因为我没有意识到我在CredentialsAuthProvider类的TryAuthenticate方法的IServiceBase参数中获得了所需的所有信息。
最后我得出了以下解决方案:
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);
}
}
答案 1 :(得分:0)
您可以按照优先顺序在ServiceStack Authentication期间将Url设置为重定向到的不同位置:
http://geocoder.cit.api.here.com/6.2/geocode.json?prox=43.260204,76.914597,30000&searchtext=Zhibek-Zholy, Almaty&country=KAZ&app_id=MY_APP_ID&app_code=MY_APP_CODE&gen=8&maxresult=100&language=en
网址(如果已填充Session.ReferrerUrl
发出请求时,继续 QueryString,FormData参数(即Authenticate.Continue属性)/auth