DNOA仅在实时生产服务器上出错

时间:2014-10-28 11:23:54

标签: asp.net-mvc asp.net-mvc-4 iis oauth-2.0 dotnetopenauth

我遇到的登录过程出现问题只会在实时服务器上发生,这使得解决这个问题变得非常尴尬。我也有点担心为什么这只会在现场服务器以及问题本身上发生。

我有三个系统实例,我在Visual Studio中开发并使用IISExpress进行开发和调试,我还有一个虚假的“staging”实例,我使用本地SSL保护的IIS网站然后我有实时生产我在虚拟专用服务器上的虚拟主机公司环境。

我只在VDS中的托管版本上看到过这个问题。

该网站包含一个MVC4网站和一个受OAuth保护的API,托管在服务器上的一个单独的IIS站点中。

问题

登录到生产站点时,在登录过程中似乎打嗝并向用户显示两次登录屏幕。再次单击登录,用户即可正确登录。

DNOA错误消息

DotNetOpenAuth.Messaging.ProtocolException:收到的回调和客户端状态与预期值不匹配的意外OAuth授权响应。

代码 - AccountController

public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid && SecurityClient.Login(model.Email, model.Password, model.RememberMe))
    {
        ObtainApiOAuthTokens(model.Email, returnUrl);
    }
}

public void ObtainMoodexApiOAuthTokens(string userName, string returnUrl)
{
    var scopes = SecurityClient.GetOauthScopesForCurrentUser(userName);
    _client.GetAuthorised(scopes, returnUrl);
}

代码 - APIClient

public void GetAuthorised(IEnumerable<string> scopes, string returnUrl)
{
    if (!string.IsNullOrEmpty(returnUrl))
    {
        var nvc = new NameValueCollection { { "returnUrl", returnUrl } };
        RequestUserAuthorization(scopes, new Uri(ConfigurationManager.AppSettings["TokenCallbackUrl"] + nvc.ToQueryString(false)));
    }
    else
    {
        RequestUserAuthorization(scopes, new Uri(ConfigurationManager.AppSettings["TokenCallbackUrl"]));
    }
}

代码 - AccountController - ReadTokens

public ActionResult ReadTokens()
{
    if (!string.IsNullOrEmpty(Request.QueryString["code"]))
    {
        try
        {
            IAuthorizationState authorization = _client.ProcessUserAuthorization();
            authorization.Callback = new Uri(authorization.Callback.GetLeftPart(UriPartial.Path));

            if (!string.IsNullOrEmpty(authorization.AccessToken))
            {
                _client.SaveState(authorization);
            }
        }
        catch (ProtocolException ex)
        {
            _log.Fatal("Error reading security tokens", ex);
        }
    }

    string[] roles = Roles.GetRolesForUser(User.Identity.Name);
    if (roles.Contains(AppRole.LicenseManager.ToString()))
    {
        return RedirectToAction("index", "licenseadmin", new { @area = "licensemanager" });
    }

    var returnUrl = Request.QueryString["returnUrl"];
    if (string.IsNullOrEmpty(returnUrl))
    {
        return RedirectToAction("index", "dashboard");
    }

    return RedirectToLocal(returnUrl);
}

由于我将[Authorize]属性应用于全局过滤器集合,因此未使用[AllowAnonymous]显式“打开”的所有方法都需要对用户(请求)进行身份验证。由于ReadTokens回调是在初始Login请求的上下文中执行的,因此可以安全地假设这就是用户被重定向回Login视图的原因吗?由于响应尚未发送回客户端,因此请求尚未通过身份验证。

解决此问题的最佳方法是什么?此外,如果这是问题的根本原因,为什么这只会在使用系统的生产实例时出现?

2 个答案:

答案 0 :(得分:0)

出于好奇,请检查生产服务器上的时钟是否正确。

答案 1 :(得分:0)

只是为了完整性这个问题。我最终追查了这个问题。当我部署到生产服务器时,我忽略了添加XML转换,对配置文件进行了某些更改。

所有其他浏览器似乎没有任何障碍,但Chrome并未在后续请求中可靠地返回身份验证Cookie。

添加转化以在Cookie上设置domain属性(例如:.example.com)后,Chrome的问题就会消失。