c# - mvc 应用程序中的表单例份验证,使用外部服务进行身份验证

标签 c# asp.net-mvc security asp.net-mvc-4 forms-authentication

我目前正在开发一个 MVC4 应用程序,不同类型的用户可以访问该网站并登录。将有 2 种不同的用户类别,类型 A 和 B,可以访问网站的不同区域。

用户的身份验证是通过对身份验证提供商的服务调用进行的,他们将返回用户是否已通过身份验证的状态以及用户信息,例如姓名、地址等。此时,我想跟踪用户经过身份验证以及他们的角色。以前,我会创建一个包含用户名、地址等的 cookie,并将其存储在客户端计算机上。但这很容易被操纵,因为 cookie 是纯文本。

但我想加强网站的安全性,因此考虑使用 FormsAuthentication。我知道这会生成一个cookie,但它更安全。

这是正确的方法吗?地址等用户信息是否可以存储在该 cookie 中?我想要存储它的 session 不可用。我如何使用 FormsAuthentication 实现此目的?

我的第二个问题是,用户登录后,我如何知道他们所处的角色?

最后,一旦用户登录,整个网站是否应该通过 https 访问?即使是对所有人开放但已登录用户可以访问的区域?登录的用户将在每个页面的屏幕上显示他们的信息,例如欢迎约翰。

最佳答案

Is this the correct approach and can the users information such as address etc be stored in this cookie?

您说得对,表单例份验证默认情况下会将用户详细信息存储在加密的 cookie 中,因此它比您现在拥有的更安全。

通过表单例份验证,您可以指定进入客户端 cookie 的字符串内容。不过,我认为您应该在 cookie 中存储的唯一信息是用户标识符和角色标识符。此信息应该是根据请求对用户进行身份验证和授权所需的全部信息。任何额外的信息(例如地址)只会增加 cookie 的权重,并且可以在需要时从服务中获取。

要使用表单例份验证,只需将身份验证元素添加到 system.web 部分内的 web.config 中即可:

<authentication mode="Forms">
  <forms loginUrl="~/Login/Home" timeout="60" />
</authentication>

调用服务来验证用户后,通过 FormsAuthentication 静态类设置 Cookie 数据。 Cookie 数据需要包含用户的标识符(例如,如果您想显示用户的姓名)和角色标识符(如下所述)。

var username = // get name from service
var role = // get role from service
FormsAuthentication.SetAuthCookie(username + "-" + role, keepUserLoggedIn);

使用相同的类在用户注销时删除 cookie。

FormsAuthentication.SignOut();

My second question is, once a user is logged in, how do I know the role that they are in?

asp.net MVC 提供了一种简单的机制,仅允许特定用户访问应用程序的区域。通过在任何 Controller 类或操作方法上使用 [Authorise] 属性,仅允许登录的用户访问 - 即存在 FormsAuthentication cookie 的用户。未登录的用户将被重定向到 web.config 的身份验证元素中指定的 LoginUrl。

Authorize 属性还有一个重载,仅允许特定角色的用户访问 Controller /方法。这将只允许具有“管理员”角色的登录用户访问 Controller 的任何操作方法。

[Authroise("Admin")]
public class EditController : Controller
{}

然后,您需要创建自己的系统接口(interface) RoleProvider 实现。该接口(interface)包含许多方法,但并非所有方法都是必需的。要检查用户所处的角色,您需要实现的唯一方法是 GetRolesForUser[Authorise] 属性将使用它来确定用户是否可以查看。

public class MyRoleProvider : RoleProvider
{
    public override string[] GetRolesForUser(string username)
    {
        var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null && !String.IsNullOrEmpty(authCookie.Value))
        {
            var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            var roles = authTicket.UserData.Split(',')[1];
            return roles.Split(';');
        }

        throw new MemberAccessException("User not logged in");
    }
}

然后,您只需在 Authorise] 属性启动时告诉您的应用程序使用 RoleProvider 的实现即可。这也是通过system.web 元素。

<roleManager defaultProvider="MyRoleProvider" enabled="true">
  <providers>
    <clear />
    <add name="MyRoleProvider" type="My.Namespace.MyRoleProvider" />
  </providers>
</roleManager>

Finally, once a user is logged in, should the entire site by https? Even areas that are open to everyone but being visited by the logged in user?

理想情况下,是的。用户登录并且您设置了 FormsAuthentication cookie 后,您需要保护该 cookie 免受外部拦截。为了防止这种情况,您应该在应用程序的所有区域强制执行 https 协议(protocol)。如果用户的请求被拦截并制作了 cookie 的副本,那么“中间人”就可以在他的浏览器中设置 cookie 的副本并获得对您网站 protected 区域的访问权限。使用 MVC,您可以在任何特定 Controller 或操作方法上使用 [RequireHttpsAttribute],类似于 [Authorise] 属性。在 MVC4 中,有一种简单的方法可以“全局”应用此功能。在 Web 项目的 App_Start 文件夹中,找到 FilterConfig 类,并将以下行添加到 RegisterGlobalFilters 方法中:

filters.Add(new RequireHttpsAttribute());

关于c# - mvc 应用程序中的表单例份验证,使用外部服务进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13000770/

相关文章:

c# - 通过 SSL 查询 AD 域

.net - 如何扩展 Html.ValidationMessage 以便我可以包含图像作为错误?

.net - 如何修复 System.Data.Edm.EdmEntityType 没有键

rest - 公开记录开放 API 是一种好习惯吗?

javascript - 我应该用 Mongoose 验证获取参数吗

c# - 是否可以从第一个元素以外的元素开始迭代使用 foreach?

c# - MongoDb 驱动程序中的 Lambda 语法用于更新文档中的数组元素

c# - 如何更新sql server表中的选择性行?

asp.net-mvc - .net MVC、SelectLists 和 LINQ

security - HAProxy 是否默认保护自己免受 tcp syn flood 攻击