gpt4 book ai didi

c# - System.InvalidOperationException 的未处理异常破坏了我的 MVC 应用程序?

转载 作者:太空宇宙 更新时间:2023-11-03 10:29:19 24 4
gpt4 key购买 nike

我正在考虑 building a OWIN login from a empty MVC 的概念在创建身份声明以放入 URL 后,我才开始添加使用我的数据库登录用户的部分。

这是我创建用户登录声明的代码

public class AuthenticationController : Controller
{
IAuthenticationManager Authentication
{
get { return HttpContext.GetOwinContext().Authentication; }
}

[GET("Login")]
public ActionResult Show()
{
return View();
}

[POST("Login")]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel input)
{
if (ModelState.IsValid)
{
if (input.HasValidUsernameAndPassword())
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, input.Username),
},
DefaultAuthenticationTypes.ApplicationCookie,
ClaimTypes.Name, ClaimTypes.Role);

// if you want roles, just add as many as you want here (for loop maybe?)
if (input.isAdministrator)
{
identity.AddClaim(new Claim(ClaimTypes.Role, "Admins"));
}
else
{
identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
}
// tell OWIN the identity provider, optional
// identity.AddClaim(new Claim(IdentityProvider, "Simplest Auth"));

Authentication.SignIn(new AuthenticationProperties
{
IsPersistent = input.RememberMe
}, identity);

return RedirectToAction("show", "authentication");
}
}
return View("show", input);
}

[GET("logout")]
public ActionResult Logout()
{
Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Login");
}
}

这是我的 Show.cshtml 代码

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Details</h4>
<hr />
@Html.ValidationSummary(true)

<div class="form-group">
@Html.LabelFor(model => model.Username, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Username)
@Html.ValidationMessageFor(model => model.Username)
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.RememberMe, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.RememberMe)
@Html.ValidationMessageFor(model => model.RememberMe)
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
</div>
</div>
</div>
}

这是我调用数据库并为登录用户存储数据的代码

public class LoginModel
{
[Required]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }

public bool RememberMe { get; set; }

public bool isAdministrator { get; set; }

public bool HasValidUsernameAndPassword()
{
bool result = false;
int countChecker = 0;
using (SqlConnection connection = new SqlConnection("server=server; database=db; user id=user; password=user"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT count(*) FROM ACCOUNTS WHERE active = 1 AND UserName = @param1 AND PasswordField = @param2", connection))
{
command.Parameters.Clear();
command.Parameters.AddWithValue("@param1", Username);
command.Parameters.AddWithValue("@param2", Password);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
countChecker = Convert.ToInt32(reader[i].ToString());

}
}
if (countChecker > 0)
{
result = true;
using (SqlConnection connect = new SqlConnection("server=server; database=db; user id=user; password=user"))
{
connect.Open();
using (SqlCommand com = new SqlCommand("SELECT Administrator FROM ACCOUNTS WHERE active = 1 AND UserName = @param1 AND PasswordField = @param2", connect))
{
com.Parameters.Clear();
com.Parameters.AddWithValue("@param1", Username);
com.Parameters.AddWithValue("@param2", Password);
SqlDataReader read = com.ExecuteReader();
while (read.Read())
{
for (int i = 0; i < read.FieldCount; i++)
{
isAdministrator = Convert.ToBoolean(read[i].ToString());
}
}
}
connect.Dispose();
connect.Close();
}
}
else
{
result = false;
}
}
connection.Dispose();
connection.Close();
}
return result;
}
}

我的登录(LoginModel 输入)完成并返回到 Show.cshtml,然后在此处出现异常 @Html.AntiForgeryToken()。我得到的异常(exception)是:

A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was not present on the provided ClaimsIdentity. To enable anti-forgery token support with claims-based authentication, please verify that the configured claims provider is providing both of these claims on the ClaimsIdentity instances it generates. If the configured claims provider instead uses a different claim type as a unique identifier, it can be configured by setting the static property AntiForgeryConfig.UniqueClaimTypeIdentifier.

我是使用 MVC 的新手,我无法判断 ActionResult Login(LoginModel input) 中缺少两者中的哪一个。有人可以向我解释我缺少哪一个吗。

我将 Corey 的建议添加到我的 Global.asax 中:

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
AttributeRoutingConfig.RegisterRoutes(RouteTable.Routes);
}
}

现在我明白了:

Additional information: A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was not present on the provided ClaimsIdentity.

我更改了 AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;到 AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;我再也没有异常(exception)。这是正确的语法吗?

最佳答案

article可能有帮助:

Unfortunately this error is a little confusing because it says “nameidentifier or identityprovider” even though you may have one of the two. By default you need both.

Anyway, if you’re not using ACS as your STS then the above error pretty much tells you what’s needed to solve the problem. You need to tell MVC which claim you want to use to uniquely identify the user. You do this by setting the AntiForgeryConfig.UniqueClaimTypeIdentifier property (typically in App_Start in global.asax). For example (assuming you want to use nameidentifier as the unique claim):

protected void Application_Start()
{
...

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}

关于c# - System.InvalidOperationException 的未处理异常破坏了我的 MVC 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30765533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com