为什么其他机器在从一台计算机注册后没有返回 OAuthWebSecurity.Login() 的 OAuthWebSecurity.Login() "true"?



我有一个奇怪的小错误,只有当机器从另一台机器注册到我们的网站后,试图通过Google OAuth登录时才会发生。

我有一个部分CMS,只有我们的员工可以通过一个简单的按钮点击登录(尽管它是非CMS部分的公共网站)。

登录的一切似乎都很好,但一旦"注册",也就是说,我们的数据库中已经有一个现有帐户,用户试图从另一台计算机登录,C#if(registered)等同于false,并将用户视为试图注册,而不仅仅是登录,这是由我的代码处理的,显示一个错误页面,上面写着,"该用户已注册"。

有问题的逻辑分支:

bool registered = OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false);
if (registered)
{
Context.RedirectLocal(returnUrl);
return;
}

这是整个cshtml文件:

@{
WebSecurity.Logout();
string email = "";
string loginData = "";
string providerDisplayName = "";
var errorMessage = "";
var db = Database.Open("Accounts");
var returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl.IsEmpty())
{
returnUrl = Href("~/CMS Interface/AdminLogin.cshtml");
}
if (IsPost && Request.Form["newAccount"].AsBool())
{
email = Request.Form["userName"];
loginData = Request.Form["loginData"];
string provider = "";
string providerUserId = "";
if (WebSecurity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(loginData, out provider, out providerUserId))
{
Context.RedirectLocal("~/");
return;
}
providerDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName;
db.Execute("INSERT INTO UserProfile (Email, IPAddress) VALUES (@0, @1)", email, Request.UserHostAddress);
Roles.AddUserToRole(email, "Locked");
OAuthWebSecurity.CreateOrUpdateAccount(providerDisplayName, providerUserId, email);
OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
Context.RedirectLocal(returnUrl);
return;
}
else
{
var result = OAuthWebSecurity.VerifyAuthentication(Href("~/Account/RegisterService", new { returnUrl }));
if (result.IsSuccessful)
{
bool registered = OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false);
if (registered) //This doesn't equate to true after user is already registered, although it should.
{
Context.RedirectLocal(returnUrl);
return;
}
email = result.UserName;
if (!EmailValidator.IsEmailAdress(email))
{
errorMessage = "The email address supplied was not a valid email address. ";
errorMessage += "Please return to the main page and try again. If the problem ";
errorMessage += "persists, please notify a site administrator for help.<br/><br/>";
errorMessage += "<a class="retreatLink" href="/">Main Page</a>";
}
if (!email.EndsWith("@okmcity.net"))
{
errorMessage = "Your email address was valid, however, it seems that it's ";
errorMessage += "not a "City of Okmulgee" email address. Please ensure that ";
errorMessage += "your email address is part of the "@okmcity.net" domain.<br/><br/>";
errorMessage += "If you are having trouble changing your email address ";
errorMessage += "try visiting Google's <a href="https://mail.google.com">Gmail</a> ";
errorMessage += "page and logging out. After you have logged out of gmail, revisit ";
errorMessage += "the <a href="/">main page</a> and click the ";
errorMessage += ""Log-in!" button again. Then, when prompted by Gmail services, ";
errorMessage += "log back in using a valid "okmcity.net" email address.<br/><br/>";
errorMessage += "For more help visit <a href="https://support.google.com/mail/answer/8154?hl=en">";
errorMessage += "Gmail Help</a> for quick steps on how to log-out of your Gmail account.";
}
if (errorMessage == "")
{
email = email.Substring(0, email.IndexOf("@"));
}
var user = db.QuerySingle("SELECT Email FROM UserProfile WHERE LOWER(Email) = LOWER(@0)", email);
if (user != null)  //This branch equates to true when user is already registered (as it should, as a failsafe, except that the code should never reach this far down in the first place when a user is registered.
{
errorMessage = "The user " + email + " already exists. You cannot register twice. ";
errorMessage += "Please revisit the <a href="/">main page</a> and click the "Log-in!" ";
errorMessage += "button again. If this problem persists, please notify a site administrator ";
errorMessage += "for help.";
}
loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
providerDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
}
else
{
Context.RedirectLocal("~/Account/ExternalLoginFailure");
return;
}
}
}
<div class="subWrapper">
<h2>Associate your @providerDisplayName account.</h2>
<form method="post">
<input type="hidden" name="loginData" value="@loginData" />
<fieldset class="regBox">
<legend class="regBox">Registration</legend>
@if (errorMessage == "")
{
<p>
You've successfully authenticated with <strong>@providerDisplayName</strong>. Please
click the &quot;Confirm&quot; button to log-in and finish registering.
</p>
<div>
<span>
<label for="userName">Your User Name:</label>
<input type="text" id="userName" name="userName" readonly="true" value="@email" />
</span>
</div><br/>
<button type="submit" class="loginBtn" name="newAccount" value="true">Confirm</button>
}
else
{
<p class="errorMessage">
@Html.Raw(errorMessage)
</p>
}
</fieldset>
</form>
</div>

然而,问题是,在原始机器上,一旦注册,一切都很好,if(registered)条件等于true。

你必须原谅我,我对OAuth了解不多。尽管我以前也使用过它,但我主要是通过在打字时逐行阅读它来理解它,偶尔也会在MSDN上查找一些方法的帮助。

我不得不根据我们的具体需求重新设计默认设置,尽管代码基本相同。可能是我把这里搞砸了。

在尝试用谷歌搜索这个并在这里搜索SO之后,我找不到任何相关的东西。此外,我真的不了解这个问题的本质,所以我不知道我是否遗漏了任何有助于解决这个问题的信息。如果是,请告诉我。

你可能想知道的事情

Google是我们唯一需要的OAuth(或openID)身份验证。

我在一个带有Webmatrix(C#)环境的ASP.NET网页中工作。

我刚刚看到了完全相同的问题,这是由WebDeploy在部署过程中替换数据库连接字符串引起的(它出于某种原因要求我选择它们,尽管它们已经在web.config中指定了)。不知怎的,我的三个连接字符串只得到了两个值,这意味着其中一个是错误的,即用于用户帐户的连接字符串。这意味着,当它查找登录者的用户ID时,整个过程都失败了(表甚至不在那里!)并且不知何故,该错误被抑制,只返回false。

最新更新