2015-10-15 24 views
0

我有一个身份验证提供程序,它在ServiceStack中使用HMAC作为身份验证机制。ServiceStack IHttpRequest.AbsoluteUri不匹配浏览器客户端Uri

我正在使用IHttpRequest.AbsoluteUri来获取Uri,但Uri不是我所期望的。由于Uri是我用于HMAC的HMAC基本字符串的核心部分,因此验证在我们的预生产服务器上失败。

private string BuildBaseString(IHttpRequest req, string accountCode, string username, string timestamp) 
{ 
    var methodType = req.HttpMethod; 
    var absoluteUri = req.AbsoluteUri; 
    return string.Join("\n", methodType, timestamp, absoluteUri, accountCode, username).ToUpper(); 
} 

我使用ServiceStack的超棒日志记录功能记录所有事情。我的假设是,输入到REST客户端的URL将与IHttpRequest.AbsoluteUri相同。但是,我认为这是一个很小但显着的差异,这是由负载平衡器造成的。

https://service.com/auth/hmac 

被转换为绝对URI:

https://service.com:80/auth/hmac 

(我可以看到这个在ServiceStack日志)

的问题是,是否有更好的IHttpRequest财产,我应该使用到避免这种情况,还是我需要在C#中自己手动分解Uri来去掉端口号?后者似乎有点冒失。

更新:

我知道这会工作,但有没有更好的方法?

var req = authService.RequestContext.Get<IHttpRequest>(); 
var u = new System.Uri(req.AbsoluteUrl); // https://service.com:80/auth/hmac 
string clean = u.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped); 
Console.WriteLine(clean); // https://service.com/auth/hmac 

回答

0

您的客户端是否也是C#结束(就像在控制器中一样)。如果是这样,那么你可以从你的其他URL(没有端口号)创建一个新的System.Uri,然后对它做一个ToString。

通过这种方式,您可以直接使用相同的解析来比较URL。优于剥离端口,因为它允许不同的端口号不同。

+0

我不知道我跟着你。客户端不承担任何端口。服务器AbsoluteUri返回带有端口的Uri。你是否建议:'var u1 = new UriBuilder(req.AbsoluteUri);字符串干净= u1.Uri.ToString();'因为那也包括端口? 主要是因为:“当端口是该方案的默认端口时,此方法返回的字符串不包含端口信息。” (msdn.microsoft.com/en-us/library/system.uri.tostring.aspx) – Junto

+0

是的,我建议比较中的两个Uri都被实例化为System.Uri。关于未返回端口号的注释不相关,因为相同的Urls将以完全相同的方式呈现,按照方法的规则显示或扣留端口号。如果他们渲染不同,那么肯定会有区别。 –

+0

我想这是我的问题。负载均衡器故意将端口添加到请求URI中。客户端发出的初始请求不指定端口,因此进程失败。我建议的解决方案在上面,但我一直在寻找改进,特别是已经内置到ServiceStack IHttpRequest中的解决方案,这是一个围绕Http.Current.Request的松散包装 – Junto