如何在ASP.NET MVC 5中实现自定义身份验证

Gia*_*chi 75 c# authentication asp.net-mvc authorization asp.net-identity

我正在开发一个ASP.NET MVC 5应用程序.我有一个现有的数据库,我从中创建了我的ADO.NET实体数据模型.我在该DB中有一个包含"username"和"password"列的表,我想用它们在我的Webapp中实现身份验证和授权; 我无法创建任何其他数据库或表或列,因为客户的要求,我无法使用标准身份验证.我不需要管理注册,密码更改或其他内容:只需使用密码和用户名登录.我怎样才能做到这一点?

Sam*_*ari 149

是的你可以.身份验证和授权部分独立工作.如果您有自己的身份验证服务,则可以使用OWIN的授权部分.考虑一下你已经有一个UserManager验证usernamepassword.因此,您可以在回发登录操作中编写以下代码:

[HttpPost]
public ActionResult Login(string username, string password)
{
    if (new UserManager().IsValid(username, password))
    {
        var ident = new ClaimsIdentity(
          new[] { 
              // adding following 2 claim just for supporting default antiforgery provider
              new Claim(ClaimTypes.NameIdentifier, username),
              new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),

              new Claim(ClaimTypes.Name,username),

              // optionally you could add roles if any
              new Claim(ClaimTypes.Role, "RoleName"),
              new Claim(ClaimTypes.Role, "AnotherRole"),

          },
          DefaultAuthenticationTypes.ApplicationCookie);

        HttpContext.GetOwinContext().Authentication.SignIn(
           new AuthenticationProperties { IsPersistent = false }, ident);
        return RedirectToAction("MyAction"); // auth succeed 
    }
    // invalid username or password
    ModelState.AddModelError("", "invalid username or password");
    return View();
}
Run Code Online (Sandbox Code Playgroud)

您的用户管理器可以是这样的:

class UserManager
{
    public bool IsValid(string username, string password)
    {
         using(var db=new MyDbContext()) // use your DbConext
         {
             // for the sake of simplicity I use plain text passwords
             // in real world hashing and salting techniques must be implemented   
             return db.Users.Any(u=>u.Username==username 
                 && u.Password==password); 
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以通过添加Authorize属性来保护您的操作或控制器.

[Authorize]
public ActionResult MySecretAction()
{
    // all authorized users can use this method
    // we have accessed current user principal by calling also
    // HttpContext.User
}

[Authorize(Roles="Admin")]
public ActionResult MySecretAction()
{
    // just Admin users have access to this method
} 
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚更新了我的帖子来回答你的问题. (7认同)
  • 嘿,我想让你知道你的github示例(为了tokenauth)解决了我的问题,非常感谢!如果可以的话,我会将你的例子提升1000次:) (5认同)
  • 需要的nuget包: - Microsoft.AspNet.Identity.Core - Microsoft.AspNet.Identity.Owin - Microsoft.Owin - Microsoft.Owin.Host.SystemWeb - Microsoft.Owin.Security - Microsoft.Owin.Security.Cookies - Microsoft.Owin .Security.OAuth - Owin (5认同)
  • 我希望你有这个问题的开放赏金,所以我们可以给你+1000.请在博客上的某个地方发布,以便搜索引擎可以达到此目的.它是如此简单而优雅的解决方案.我花了两天时间阅读有关OWIN和OAuth2提供的内容,而我无法连接电线. (5认同)
  • 完美答案+1 (2认同)
  • @SamFarajpourGhamari:你能解释为什么`Login`代码中需要长const字符串吗?`... new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider","ASP.NET Identity","http://www.w3.org/2001/XMLSchema #string")`我检查过代码在没有它的情况下工作得很好! (2认同)
  • 该解决方案似乎是 OWIN 特定的。-- 在常规 MVC 中我们如何做到这一点?-- 无论如何,仅仅添加 NuGet 包是不够的,您会得到一堆关于缺少 `OwinStartupAttribute` 和缺少配置设置的代码...... (2认同)