我遇到的登录过程出现问题只会在实时服务器上发生,这使得解决这个问题变得非常尴尬。我也有点担心为什么这只会在现场服务器以及问题本身上发生。
我有三个系统实例,我在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
视图的原因吗?由于响应尚未发送回客户端,因此请求尚未通过身份验证。
解决此问题的最佳方法是什么?此外,如果这是问题的根本原因,为什么这只会在使用系统的生产实例时出现?
答案 0 :(得分:0)
出于好奇,请检查生产服务器上的时钟是否正确。
答案 1 :(得分:0)
只是为了完整性这个问题。我最终追查了这个问题。当我部署到生产服务器时,我忽略了添加XML
转换,对配置文件进行了某些更改。
所有其他浏览器似乎没有任何障碍,但Chrome并未在后续请求中可靠地返回身份验证Cookie。
添加转化以在Cookie上设置domain
属性(例如:.example.com
)后,Chrome的问题就会消失。