我使用 MVC 4 附带的标准 OAuth 功能让用户使用 Google 和 Facebook 登录。一切正常,直到我使用 url rewrite 从我的 godaddy 托管站点中删除虚拟目录名称(请参阅http://support.godaddy.com/library/removing-virtual-application-name-from-urls/)
Facebook 仍然可以正常工作,但谷歌现在每次都失败了。Google 会重定向回正确的 url,但是当 OAuth 库尝试从 url 中获取信息时,它的行为就好像它不存在一样。
我不知道为什么,但我知道它与 url 重写有关,因为当我手动将虚拟目录名称添加到它工作的返回 url 时(但 facebook 中断)。
这是 web.config 中删除虚拟目录的代码:
<rule name="Remove Virtual Directory">
<match url=".*" />
<action type="Rewrite" url="{R:0}" />
</rule>
这是 OAuth 代码:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
var action = Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl });
return new ExternalLoginResult(provider, action);
}
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
var action = Url.Action("ExternalLoginCallback", new{ReturnUrl = returnUrl});
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(action);
//AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication();
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
尽管提供者名称在 url 中清晰可见,但这一切似乎都在这里分崩离析:
public static string GetProviderName(HttpContextBase context)
{
return context.Request.QueryString[ProviderQueryStringName];
}
编辑:
通过将外部登录处理程序更改为:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
var action = Url.Action("ExternalLoginCallback", new {ReturnUrl = returnUrl});
var mustHackGodaddy = provider == "google";
if (mustHackGodaddy){
action = "/[virtual directory name]" + action;
}
return new ExternalLoginResult(provider, action);
}
不过,我真的不会称其为解决方案。任何人都可以阐明发生了什么吗?我想知道 oauth 库是否因为重写了 url 而认为这是一次 xss 攻击。但奇怪的是它只对谷歌中断,并且请求也是从同一个 url 发出的。