【发布时间】:2014-10-28 11:23:53
【问题描述】:
我在登录过程中遇到了仅在实时服务器上发生的问题,这使得解决此问题变得非常尴尬。我也有点担心为什么这似乎只发生在实时服务器以及问题本身上。
我有三个系统实例,我在 Visual Studio 中开发并使用 IISExpress 进行开发和调试,我还有一个人造的“登台”实例,我使用本地 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 视图的原因吗?由于尚未将响应发送回客户端,因此请求尚未经过身份验证。
解决此问题的最佳方法是什么?另外,如果这是问题的根本原因,为什么只会在使用系统的生产实例时出现?
【问题讨论】:
标签: asp.net-mvc asp.net-mvc-4 iis oauth-2.0 dotnetopenauth