2

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

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

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

这是正确的方法吗?用户信息(例如地址等)是否可以存储在此 cookie 中?我想存储它的会话对我不可用。我将如何使用 FormsAuthentication 实现这一点?

我的第二个问题是,一旦用户登录,我怎么知道他们的角色?

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

4

1 回答 1

4

这是正确的方法吗?用户信息(例如地址等)是否可以存储在此 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();

我的第二个问题是,一旦用户登录,我怎么知道他们的角色?

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

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

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

然后您需要创建您自己的系统接口实现RoleProvider。该接口包含许多方法,但并非所有方法都是必需的。您需要实施以检查用户所在角色的唯一方法是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");
    }
}

然后,您只需要告诉您的应用程序使用属性RoleProvider何时Authorise]启动的实现。这也可以通过 system.web 元素中的 web.config 完成。

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

最后,一旦用户登录,整个网站是否应该通过https?即使是对所有人开放但由登录用户访问的区域?

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

filters.Add(new RequireHttpsAttribute());
于 2012-10-21T19:53:44.437 回答