ASP.NET MVC表单身份验证+授权属性+简单角色

Kev*_*vin 54 asp.net-mvc authorization forms-authentication

我正在尝试向ASP.NET MVC应用程序添加简单的身份验证和授权.

我只是试图在基本的表单身份验证上增加一些功能(由于简单性和自定义数据库结构)

假设这是我的数据库结构:用户:用户名密码角色(理想情况下是一些枚举.如果需要,则为字符串.目前,用户只有一个角色,但这可能会改变)

高级问题:鉴于上述数据库结构,我希望能够做到以下几点:

  • 使用表单身份验证简单登录
  • 用以下方式装饰我的行为:[授权(角色= {MyRoles.Admin,MyRoles.Member})]
  • 在我的视图中使用角色(以确定在某些部分中显示的链接)

目前,我真正确定的是如何进行身份验证.在那之后,我迷路了.我不确定我在哪个位置获取用户角色(登录,每次授权?).由于我的角色可能不是字符串,我不确定它们如何适应User.IsInRole().

现在,我在这里问,因为我没有找到一个"简单"完成我需要的东西.我见过多个例子.

对于身份验证

  • 我们有简单的用户验证来检查数据库和"SetAuthCookie"
  • 或者我们覆盖成员资格提供程序并在ValidateUser中执行此操作.在其中任何一个中,我不确定如何处理我的简单用户角色,以便它们使用:HttpContext.Current.User.IsInRole("Administrator")此外,我不知道如何修改它以使用我的枚举值.

对于授权,我看到:

  • 派生AuthorizeAttribute并实现AuthorizeCore OR OnAuthorization来处理角色?
  • 实施IPrincipal?

任何帮助将不胜感激.但是,我担心我可能需要很多细节,因为我用Google搜索的内容似乎都不适合我需要做的事情.

yin*_*ner 119

我想我已经实现了类似的东西.
我的解决方案基于NerdDinner 教程,正在关注.

当您为用户签名时,添加如下代码:

var authTicket = new FormsAuthenticationTicket(
    1,                             // version
    userName,                      // user name
    DateTime.Now,                  // created
    DateTime.Now.AddMinutes(20),   // expires
    rememberMe,                    // persistent?
    "Moderator;Admin"                        // can be used to store roles
    );

string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
Run Code Online (Sandbox Code Playgroud)

将以下代码添加到Global.asax.cs:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie == null || authCookie.Value == "")
        return;

    FormsAuthenticationTicket authTicket;
    try
    {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch
    {
        return;
    }

    // retrieve roles from UserData
    string[] roles = authTicket.UserData.Split(';');

    if (Context.User != null)
        Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以在控制器操作代码中使用[Authorize]属性:

[Authorize(Roles="Admin")]
public ActionResult AdminIndex ()
Run Code Online (Sandbox Code Playgroud)

如果您有其他问题,请告诉我.

  • 我试过这个,但Context.User对我来说总是空的.也许我需要在web.config中更改一些东西.但是,我通过删除'if(Context.User!= null)'并将Application_AuthenticateRequest中的最后一行更改为'Context.User = new GenericPrincipal(new GenericIdentity(authTicket.Name),roles);'来实现它. (4认同)
  • 如果它不适合你,只需在Web.config中添加`<appSettings> <add key ="enableSimpleMembership"value ="false"/> </ appSettings>`. (3认同)

Nea*_*eal 8

构建一个AuthorizeAttribute可以使用枚举而不是字符串的自定义.当您需要授权时,通过附加枚举类型名称+枚举值将枚举转换为字符串并使用IsInRolefrom.

要将角色添加到授权用户,您需要附加到HttpApplication AuthenticateRequest事件,例如http://www.eggheadcafe.com/articles/20020906.asp中的第一个代码(但将大量嵌套的if语句反转为guard子句!).

您可以在表单auth cookie中往返用户角色,也可以每次从数据库中获取它们.

  • 实际上,这正是我最终做的事情.如果你使用的是IsInRole,我终于意识到你无法解决String的问题.所以我可以在我的控制器中使用我的枚举,但是如果我需要在视图中检查角色,我会被IsInRole ... ThanX困住 (2认同)