gpt4 book ai didi

asp.net-mvc-3 - 创建 AuthorizeAttribute - 我需要知道什么?

转载 作者:行者123 更新时间:2023-12-03 23:49:38 24 4
gpt4 key购买 nike

以下是我的要求:

  • 我会将用户添加到 N 个角色中;在数据库中定义。
  • 我需要使用我的授权属性来保护每个 Controller 操作。

  • 例如,Web 应用程序将检查登录用户是否属于这两个角色中的任何一个,如果属于,我会让他们进入。 如何告诉 Authorize 属性从我选择的数据库表中获取用户角色?
     [Authorize(Roles = "Admin, Technician")]
    public ActionResult Edit(int id)
    {
    return View();
    }

    我已经尝试使用谷歌搜索许多不同的页面,但似乎没有一个适合我的需要并且过于复杂。

    如果 official documentation我也很想找到一些东西,因为我没有看到任何可以使用的东西。

    有什么建议吗?

    例如,这个问题有一个非常干净的答案,但我不知道它是否完整或遗漏了一些重要的东西。

    ASP.NET MVC3 Role and Permission Management -> With Runtime Permission Assignment

    编辑

    看来我实际上正在寻找的是创建自定义角色提供程序,对吗?我是否需要实现这个类并将其用作我的角色提供者?我对此很陌生,有什么想法吗?

    http://msdn.microsoft.com/en-us/library/8fw7xh74.aspx

    最佳答案

    在过去的几周里,我经历了几乎相同的场景,所以这可能会帮助其他人。我的场景是公司 Intranet 上的 MVC4 应用程序,用户存储在 Active Directory 中。这允许 Windows 身份验证提供单点登录,因此不需要表单例份验证。角色存储在 Oracle 数据库中。我有3个角色:

  • 只读:所有用户都需要成为此应用程序的成员才能访问应用程序
  • 用户:创建新资源
  • 管理员:编辑和删除记录

  • 我决定使用 asp.net 角色提供程序 api 来创建我自己的 AccountRoleProvider。到目前为止,我只需要使用 2 个方法,GetRolesForUser 和 IsUserInRole:
    public class AccountRoleProvider : RoleProvider // System.Web.Security.RoleProvider
    {
    private readonly IAccountRepository _accountRepository;

    public AccountRoleProvider(IAccountRepository accountRepository)
    {
    this._accountRepository = accountRepository;
    }

    public AccountRoleProvider() : this (new AccountRepository())
    {}

    public override string[] GetRolesForUser(string user521)
    {
    var userRoles = this._accountRepository.GetRoles(user521).ToArray();

    return userRoles;
    }

    public override bool IsUserInRole(string username, string roleName)
    {
    var userRoles = this.GetRolesForUser(username);

    return Utils.IndexOfString(userRoles, roleName) >= 0;
    }
    }

    我更新了 web.config 以使用我的角色提供程序:
    <authentication mode="Windows" />
    <roleManager enabled="true" defaultProvider="AccountRoleProvider">
    <providers>
    <clear/>
    <add name="AccountRoleProvider"
    type="MyApp.Infrastructure.AccountRoleProvider" />
    </providers>
    </roleManager>

    然后我从 AuthorizeAttribute、ReadOnlyAuthorize 和 CustomAuthorize 创建了 2 个自定义属性。

    只读授权:
    public class ReadonlyAuthorize : AuthorizeAttribute
    {
    private IAccountRepository _accountRepository;

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
    var user = httpContext.User;
    this._accountRepository = new AccountRepository();

    if (!user.Identity.IsAuthenticated)
    {
    return false;
    }

    // Get roles for current user
    var roles = this._accountRepository.GetRoles(user.Identity.Name);

    if (!roles.Contains("readonly"))
    {
    return false;
    }

    return base.AuthorizeCore(httpContext);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
    base.OnAuthorization(filterContext);

    if (filterContext.HttpContext.User.Identity.IsAuthenticated && filterContext.Result is HttpUnauthorizedResult)
    {
    filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
    }
    }
    }

    自定义授权:
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
    public string RedirectActionName { get; set; }
    public string RedirectControllerName { get; set; }
    private IAccountRepository _accountRepository;

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
    var user = httpContext.User;
    this._accountRepository = new AccountRepository();
    var accessAllowed = false;

    // Get the roles passed in with the (Roles = "...") on the attribute
    var allowedRoles = this.Roles.Split(',');

    if (!user.Identity.IsAuthenticated)
    {
    return false;
    }

    // Get roles for current user
    var roles = this._accountRepository.GetRoles(user.Identity.Name);

    foreach (var allowedRole in allowedRoles)
    {
    if (roles.Contains(allowedRole))
    {
    accessAllowed = true;
    }
    }

    if (!accessAllowed)
    {
    return false;
    }

    return base.AuthorizeCore(httpContext);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
    base.OnAuthorization(filterContext);

    if (filterContext.HttpContext.User.Identity.IsAuthenticated && filterContext.Result is HttpUnauthorizedResult)
    {
    var values = new RouteValueDictionary(new
    {
    action = this.RedirectActionName == string.Empty ? "AccessDenied" : this.RedirectActionName,
    controller = this.RedirectControllerName == string.Empty ? "Home" : this.RedirectControllerName
    });

    filterContext.Result = new RedirectToRouteResult(values);
    }
    }
    }

    使用 2 个不同属性的原因是我将一个用于 Readonly 角色,所有用户都必须是该角色的成员才能访问该应用程序。我可以在 Global.asax 的 RegisterGlobalFilters 方法中添加它,这意味着它会自动应用于每个 Controller :
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ReadonlyAuthorize());
    }

    然后在 CustomAuthorize 中,我可以采用更精细的方法并指定我想要的角色并应用于 Controller 或单个操作,例如下面我可以将删除方法的访问权限限制为管理员角色的用户:
    [AccessDeniedAuthorize(RedirectActionName = "AccessDenied", RedirectControllerName = "Home", Roles = "Admin")]
    public ActionResult Delete(int id = 0)
    {
    var batch = myDBContext.Batches.Find(id);
    if (batch == null)
    {
    return HttpNotFound();
    }

    return View(batch);
    }

    我还需要采取其他步骤,例如使用当前用户所属的角色更新 User 对象。这将在我的自定义属性中一次而不是每次检索用户的角色,并且还利用 User.IsInRole。在 Gloal.asax 中的 Application_AuthenticateRequest 中应该可以实现这样的事情:
    var roles = "get roles for this user from respository";

    if (Context.User != null)
    Context.User = new GenericPrincipal(Context.User.Identity, roles);

    关于asp.net-mvc-3 - 创建 AuthorizeAttribute - 我需要知道什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8829685/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com