【问题标题】:Custom Authentication and ASP.NET MVC自定义身份验证和 ASP.NET MVC
【发布时间】:2013-09-06 19:23:39
【问题描述】:

我在ASP.NET 4 中构建了一个内部网络应用程序。我们坚持使用由另一个团队构建的身份验证 API。如果该站点的用户已成功通过该站点的身份验证,我想授予他们对整个站点的访问权限。

在ASP.NET WebForm 的日子里,我只是用来在会话中保留一个自定义用户对象。如果该对象为空,我知道用户未通过身份验证。 MVC 中是否有类似但改进的方法。如果可能,我不想构建自己的 ASP.NET 成员模型提供者。最简单的方法是什么?

【问题讨论】:

  • 您能否在调用旧版 API 后手动设置身份验证票证?
  • 如果设置了FormsAuthenticationTicket,可以使用Request.IsAuthenticated和User.Identity判断用户是否登录。Authorize属性也可以使用。
  • 仅供参考,在会话中处理身份验证是一个非常糟糕的主意,它不安全(cookie 未加密且容易被盗),并且容易失败,因为会话可以随时回收。改用 FormsAuthentication
  • 很好的反馈。感谢 TheKingDave、Henk、Mystere
  • 有时解决方案是在另一个问题上,有人已经在stackoverflow上做了一个非常灵活的解决方案,不需要硬编码的角色名称,有完整的代码:stackoverflow.com/questions/9043831/…

标签: c# asp.net asp.net-mvc asp.net-mvc-4


【解决方案1】:

您可以通过在登录成功时简单地输入会话变量值来进行会话身份验证。比如

public ActionResult Index(Models.Login login)
    {
        if (ModelState.IsValid)
        {
            Dal.Login dLogin = new Dal.Login();
            string result = dLogin.LoginUser(login);
            if (result == "Success")
                Session["AuthState"] = "Authenticated";
        }
        return View();
    }

现在的诀窍是,您应该拥有一个包含所有必须检查身份验证的视图的通用布局页面。在这个布局页面中,只需像这样进行剃刀检查 -

<body>
    @if (Session["AuthState"] != "Authenticated")
    {
        Response.Redirect("~/login");
    }
    // other html
</body>

我一直在我的应用程序管理面板中使用此方法。

【讨论】:

  • 请注意,这种方法很危险,可能导致会话固定或会话劫持攻击。会话 ID 永远不会更新。有关缺点的快速解释,请参阅本文。 tl;博士;您需要一个身份验证 cookie,该 cookie 对已登录的会话是唯一的,并且最好与会话相关联。 blog.securityps.com/2013/06/…
【解决方案2】:

您可以将Forms Authentication 与Authorize 属性结合使用,如下所示,

限制对视图的访问:

在action方法声明中添加AuthorizeAttribute属性,如下图,

[Authorize]
public ActionResult Index()
{
    return View();
}

在 web.config 中配置表单身份验证

<authentication mode="Forms">
     <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

登录后操作: 如果用户有效,则设置身份验证 cookie

[HttpPost]
public ActionResult Login(User model, string returnUrl)
{
        //Validation code

        if (userValid)
        {
             FormsAuthentication.SetAuthCookie(username, false);
        }
}

注销操作:

public ActionResult LogOff()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}

【讨论】:

  • 我是否必须将 [Authorize] 放在整个应用程序中的每个 Controller 方法上?我只想向匿名用户开放两个控制器方法(~/Account/Login GET 和 POST)。似乎应该有更好的方法。这需要过滤器吗?自定义属性?谢谢你的帮助。 +1
  • 在这种情况下看看这里blogs.msdn.com/b/rickandy/archive/2011/05/02/…
  • 为什么新的 ASP 身份不能像FormsAuthentication 这样简单? asp.net/identity
【解决方案3】:

您可能想要自定义authorization filter。这是一个示例:Custom filters in MVC。然后,您可以在应用启动时全局应用此过滤器(使用 RegisterGlobalFilters)。

public class LegacyAuthorize : AuthorizeAttribute
{
  public override void OnAuthorization(HttpActionContext actionContext)
  {
    if (HttpContext.Current.Session["User"] == null)
      base.HandleUnauthorizedRequest(actionContext);
  }
}

那么在你的global.asax 中你会有这样的东西:

GlobalFilters.Filters.Add(new LegacyAuthorize());

【讨论】:

【解决方案4】:

你可以试试这样的:

FormsAuthentication.SetAuthCookie(username, rememberMe);

为认证用户设置cookie,然后只需在需要认证的Controller或Action上使用[Authorize]属性。

尝试在该主题上搜索更多信息,您会发现很多关于 MVC 中的身份验证和授权的内容。

【讨论】:

    【解决方案5】:

    在 MVC 中可以在表单中执行的所有操作,只需在控制器登录操作中设置会话变量即可。

    或者你可以这样做: 在登录动作中添加formsauthentication.setauthcookie("username")

    在此之后,任何带有 [Authorize] 关键字的操作都将允许当前用户进入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多