当前位置: 首页 > 知识库问答 >
问题:

系统的未处理异常。InvalidOperationException破坏了我的MVC应用程序?

余弘毅
2023-03-14

我正在从一个空的MVC构建一个OWIN登录,我刚刚开始添加这个部分,在创建一个要放入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;
    }
}

我的登录(登录模型输入)完成并返回到Show.cshtml,然后在这里有一个异常@Html。AntiForgeryToken().我得到的例外是:

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier或http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider类型的索赔在提供的索赔身份中不存在。若要通过基于声明的身份验证启用反伪造令牌支持,请验证配置的声明提供程序是否在其生成的ClaimsId相实例上提供了这两种声明。如果配置的声明提供程序使用不同的声明类型作为唯一标识符,则可以通过设置静态属性AntiForgeryConfig来配置它。UniqueClaimType标识符。

我对使用MVC还不熟悉,我无法判断ActionResult登录(LoginModel输入)中缺少了这两个选项中的哪一个。有人能解释一下我丢了哪一个吗。

我把科里的建议加入了我的lobal.asax:

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

现在我明白了:

附加信息:类型为'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier“在所提供的索赔中不存在。

我更改了AntiForgeryConfig。UniqueClaimType标识符=声明类型。名称标识符;到AntiForgeryConfig.UniqueClaimType标识符=声明类型。名字;我没有更多的例外。这是正确的语法吗?

共有1个答案

鲁光霁
2023-03-14

本文可能有助于:

不幸的是,这个错误有点让人困惑,因为它说的是“nameidentifier或identityprovider”,即使您可能有这两个错误中的一个。默认情况下,两者都需要。

无论如何,如果你没有使用ACS作为你的STS,那么上面的错误告诉你需要什么来解决这个问题。您需要告诉MVC要使用哪个声明来唯一标识用户。您可以通过设置AntiForgeryConfig来实现这一点。UniqueClaimTypeIdentifier属性(通常在App_Start in global.asax中)。例如(假设您希望使用nameidentifier作为唯一声明):

protected void Application_Start()
{
    ...

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
 类似资料:
  • 我有一个非常简单的SOAP客户机,它是我在wsimport实用程序的帮助下针对自己的web服务创建的。客户端工作得非常好,但是当我添加一个处理程序时就崩溃了。下面是我的工作客户端,它将“1”打印到控制台... 现在,有趣的部分来了,这是同一个客户机,处理程序实现后面跟着输出... 输出 请注意,在输出中,在异常之前打印了3行,这些来自我的处理程序类,这证明它已注册并正常工作。我意识到这是一些有限的

  • 本文向大家介绍了解C++编程中指定的异常和未经处理的异常,包括了了解C++编程中指定的异常和未经处理的异常的使用技巧和注意事项,需要的朋友参考一下 noexcept C++11:指定函数是否可能会引发异常。 语法 参数 表达式 计算结果是 True 或 False 的常量表达式。无条件版本相当于 noexcept(true)。 备注 noexcept(及其同义词 noecept(true))指定函

  • 主要内容:DefaultHandlerExceptionResolver,ResponseStatusExceptionResolver,ExceptionHandlerExceptionResolver,SimpleMappingExceptionResolver在实际的应用开发中,经常会不可避免地遇到各种可预知的、不可预知的异常,此时我们就需要对这些异常处理,以保证程序正常运行。 Spring MVC 提供了一个名为 HandlerExceptionResolver 的异常处理器接口,它可以

  • 问题内容: 我正在开发一个Android应用,该应用必须将json格式的Java对象保存到SQLite数据库中。我为此操作编写了代码,然后他们必须提取Json对象并将其重新转换为Java对象。当我尝试调用将json对象反序列化为字符串的方法时,我在Android Studio中发现此错误: 当我尝试捕获程序运行但不反序列化json对象时。 这是该方法的代码: 你能帮我吗? 问题答案: 是的,您需要

  • 问题内容: JPA规范区分系统异常和应用程序异常。我对线条的确切位置感到困惑。我的猜测: 应用程序异常是您的代码或代码所使用的库显式或隐式抛出的异常。 是否包括所有异常,运行时和已检查的异常,而不管其来源如何? 系统异常可能是持久性提供程序抛出的异常。它当然包含的所有子类。 提供程序代码引发的其他异常呢? 其他Java EE库抛出的异常又如何呢? 如果将异常包装在中,是否会有所不同? 如何使用Ap

  • 我搜索了很多,几乎所有我发现的例子都使用了控制器中的异常处理和自己的异常处理程序。我一直认为这应该在程序的服务层上完成。如果不是,我真的不明白为什么要创建单独的服务层。 另外,如果我在Controller中实现异常处理,是否意味着我必须在前面的所有层中抛出异常?