您当前的位置: 首页 >  .net

寒冰屋

暂无认证

  • 0浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

使用ASP.NET MVC对用户组的自定义授权

寒冰屋 发布时间:2020-05-17 15:33:35 ,浏览量:0

目录

介绍

示例MVC应用程序进行演示

步骤1:在系统中创建新的用户角色

创建一个管理员组并映射用户

创建用户组并映射用户

步骤2:创建项目

步骤3:在Web.config中配置用户组

步骤4:添加枚举类

步骤5:添加登录视图模型

步骤6:添加授权过滤器

步骤7:添加授权助手类

步骤8:添加MVC控制器

LogInController.cs

AdminController.cs

UserController.cs

步骤9:添加MVC视图

LogIn.cshtml

Admin.cshtml

User.cshtml

步骤10:运行应用程序

介绍

本文介绍了使用ASP.NET MVC通过用户角色实现自定义授权的方法。它可以防止未经授权的用户访问不应被访问的页面。

示例MVC应用程序进行演示

在此演示应用程序中,我使用的是Visual Studio 2019。我将向您展示如何禁止用户访问不应访问的页面。我们正在使用Windows身份验证,并且仅被授权访问特定用户组(Admin/NormalUser)的用户才能访问相应页面。例如,属于Admin组的用户只能访问Admin页面,而属于Normal User组的用户只能访问NormalUser页面。

步骤1:在系统中创建新的用户角色 创建一个管理员组并映射用户

启动计算机管理窗口。创建一个新的用户组“Admin”,并将Windows用户映射到创建的组,如下图所示:

创建用户组并映射用户

启动计算机管理窗口。创建一个新的用户组“User”,并将Windows用户映射到创建的组,如下图所示:

步骤2:创建项目

在Visual Studio中,创建一个新的ASP.NET MVC Web应用程序(C#)项目,如下图所示:

步骤3:在Web.config中配置用户组

在配置文件中配置新创建的组,如下所示:


   
   
 
步骤4:添加枚举类

在项目下添加Enum “Enums.cs”类,并添加enum常量“UserRoles”,如下所示:

namespace CustomAuthorizationWithMVC
{
    public static class Enums
    {
        public enum UserGroups
        {
            /// 
            /// No roles assigned
            /// 
            None = 0,

            /// 
            /// Admin role.
            /// 
            Admin = 1,

            /// 
            /// User role.
            /// 
            NormalUser = 2,

            /// 
            /// Both Administrator and  Normal user roles.
            /// 
            All = 3
        }
    }
}
步骤5:添加登录视图模型

以下视图模型类可帮助用户存储已登录用户的详细信息。

using static CustomAuthorizationWithMVC.Enums;

namespace CustomAuthorizationWithMVC.Models
{
    public class LogInViewModel
    {
        /// 
        /// Gets or sets the LoggedInUser once Authenticated.
        /// 
        public string LoggedInUser { get; set; }

        /// 
        /// Gets or sets the Admin flag true/false.
        /// 
        public bool IsAdmin { get; set; }

        /// 
        /// Gets or sets the User Role Type.
        /// 
        public UserGroups UserGroup { get; set; }
    }
}
步骤6:添加授权过滤器

在项目下添加类文件“UserAuthorizeAttribute.cs”,并将以下代码添加到类文件中。此类继承自“AuthorizeAttribute”,并重写了方法“OnAuthorization”,该方法使用web.Config中配置的方法验证登录的组/角色。如果用户未注册到这两个组/角色中,则该用户将被重定向到登录页面,而无权访问所请求的页面。

namespace UI.UserAuthorize
{
    using System;
    using System.Configuration;
    using System.Diagnostics;
    using System.Web.Mvc;
    using System.Web.Routing;
    using static CustomAuthorizationWithMVC.Enums;
    using AuthorizeUser.Common;

    public sealed class UserAuthorizeAttribute : AuthorizeAttribute
    {
        #region Constructors

        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// allowed group types
        public UserAuthorizeAttribute(params UserGroups[] userRoleTypes)
        {
            this.AllowedUserRoleTypes = userRoleTypes;
        }

        #endregion

        #region Properties

        /// 
        /// Gets the admin user roles from configuration file.
        /// 
        private string AdminUserRoles { get; } = 
                ConfigurationManager.AppSettings["AdminUserRoles"];

        /// 
        /// Gets the user roles from configuration file.
        /// 
        private string UserRoles { get; } = ConfigurationManager.AppSettings["UserRoles"];

        /// 
        /// Gets or sets the allowed role types retrieved from controller or action method.
        /// 
        private UserGroups[] AllowedUserRoleTypes { get; set; }
    
        #endregion

        #region Public Methods

        /// 
        /// Method to do the authorization for user.
        /// 
        /// authorization context.
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext != null)
            {
                var user = filterContext.RequestContext.HttpContext.User;

                base.OnAuthorization(filterContext);
               
                If user does not have any access, redirect him to login page.
                if (!AuthorizeUser.IsAdmin(AllowedUserRoleTypes, AdminUserRoles, user) 
                    && !AuthorizeUser.IsUser(AllowedUserRoleTypes, UserRoles, user))
                {                    
                    filterContext.Result = new RedirectToRouteResult(new
                        RouteValueDictionary(new { controller = "LogIn", action = "LogIn" }));
                }               
            }
        }
        #endregion        
    }
}
步骤7:添加授权助手类

授权过滤器类“UserAuthorizeAttribute” 使用此类方法检查登录的用户是否属于已配置的Admin组或NormalUser组。

namespace AuthorizeUser.Common
{
    using System.Linq;
    using System.Security.Principal;
    using System.Text.RegularExpressions;
    using static CustomAuthorizationWithMVC.Enums;

    /// 
    /// Class to check user group
    /// 
    public static class AuthorizeUser
    {
        /// 
        /// Method to check whether user is admin user
        /// 
        /// allowed audit user group types
        /// admin user groups
        /// user
        /// true or false
        public static bool IsAdmin(UserGroups[] allowedAuditUserGroupTypes,
               string auditAdminUserGroups, IPrincipal user)
        {
            bool isAdmin = false;
            var adminUserGroups = 
                Regex.Replace(auditAdminUserGroups, @"\s", string.Empty).Split(',');

            //If allowed group is configured for Administrator.
            if (allowedAuditUserGroupTypes.Any
               (allowedGroupType => allowedGroupType == UserGroups.Admin))
            {
                isAdmin = adminUserGroups.Any(admGrp => user.IsInRole(admGrp));
            }
            return isAdmin;
        }

        /// 
        ///  Method to check whether user is audit user
        /// 
        /// allowed audit user group types
        /// admin user groups
        /// user
        /// true or false
        public static bool IsUser(UserGroups[] allowedAuditUserGroupTypes, 
             string auditUserGroups, IPrincipal user)
        {
            bool isUser = false;
            var userGroups = Regex.Replace(auditUserGroups, @"\s", string.Empty).Split(',');
            If allowed group is configured for Normal user.
            if (allowedAuditUserGroupTypes.Any
               (allowedGroupType => allowedGroupType == UserGroups.NormalUser))
            {
                isUser = userGroups.Any(usrGrp => user.IsInRole(usrGrp));
            }
            return isUser;
        }
    }
}
步骤8:添加MVC控制器

在项目的Controllers文件夹下添加以下控制器类:

  • LogInController.cs
  • AdminController.cs
  • UserController.cs
LogInController.cs

以下控制器类可帮助用户导航至“登录”视图并根据用户角色启用/禁用“登录”按钮。管理员登录按钮功能用于导航到“管理”页面,而“NormalUser登录”按钮用于将用户导航至“NormalUser”页面。

using CustomAuthorizationWithMVC.Models;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using static CustomAuthorizationWithMVC.Enums;

namespace CustomAuthorizationWithMVC.Controllers
{
    public class LogInController : Controller
    {        
        /// 
        /// Gets the admin user groups from config file.
        /// 
        private string AdminUserRoles { get; } = 
                ConfigurationManager.AppSettings["AdminUserRoles"];

        /// 
        /// Gets the user groups from config file.
        /// 
        private string UserRoles { get; } = ConfigurationManager.AppSettings["UserRoles"];

        // GET: LogIn
        public ActionResult LogIn()
        {
            // Check the user is enrolled into any of the Admin user roles.
            bool isAdmin = Regex.Replace(this.AdminUserRoles, @"\s", string.Empty).Split(',')
                            .Any(admRole => User.IsInRole(admRole));

            // Check the user is enrolled into any of the normal user roles.
            bool isUser = Regex.Replace(this.UserRoles, @"\s", string.Empty).Split(',')
                            .Any(usrRole => User.IsInRole(usrRole));

            LogInViewModel logInViewModel = new LogInViewModel()
            {
                LoggedInUser = User.Identity.Name,                
                UserGroup = this.GetUserRole(isAdmin, isUser)
            };
            return View(logInViewModel);
        }

        public ActionResult AdminView()
        {
            return this.RedirectToAction("RenderAdminView", "Admin");           
        }

        public ActionResult UserView()
        {
            return this.RedirectToAction("RenderUserView", "User");
        }

        private bool IsUserInGroup(string groupName)
        {
            return User.IsInRole(groupName);
        }
        private UserGroups GetUserRole(bool isAdmin, bool isUser)
        {
            if (isAdmin && isUser)
            {
                return Enums.UserGroups.All;
            }

            if (isAdmin)
            {
                return Enums.UserGroups.Admin;
            }

            if (isUser)
            {
                return Enums.UserGroups.NormalUser;
            }

            return Enums.UserGroups.None;
        }
    }
}
AdminController.cs

以下控制器类可帮助用户导航到“管理员”页面(如果他/她已注册为“管理员”角色)。通过在“AdminController”类之前添加“授权”过滤器“UserAuthorize”装饰(如下面的代码中突出显示的粗体所示),将针对web.cofig中配置的Admin角色验证登录用户。如果通过验证,它将执行“RenderAdminView”方法并导航到“管理”页面。否则,它将重定向到“登录”页面。

using System.Web.Mvc;
using UI.UserAuthorize;
using static CustomAuthorizationWithMVC.Enums;

namespace CustomAuthorizationWithMVC.Controllers
{
    [UserAuthorize(UserGroups.Admin)]
    public class AdminController : Controller
    {
        
       public ActionResult RenderAdminView()
       {
            return View("Admin");
       }
    }
}
UserController.cs

以下控制器类可帮助用户在已注册NormalUser角色的情况下导航至“用户”页面。通过在“UserController”类(在下面的代码中以粗体突出显示)之前进行“授权”过滤器“UserAuthorize”装饰,将针对web.config中配置的用户角色验证登录用户。如果通过验证,它将执行“RenderUserView”方法并导航到“用户”页面。否则,它将重定向到“登录”页面。

using System.Web.Mvc;
using UI.UserAuthorize;
using static CustomAuthorizationWithMVC.Enums;

namespace CustomAuthorizationWithMVC.Controllers
{
    [UserAuthorize(UserGroups.NormalUser)]
    public class UserController : Controller
    {
        public ActionResult RenderUserView()
        {
            return View("User");
        }
    }
}
步骤9:添加MVC视图

在项目的“视图”文件夹下添加以下视图:

  • LogIn.cshtml
  • Admin.cshtml
  • User.cshtml
LogIn.cshtml

在此视图中,我们收到了“LogInViewModel”作为模型,并根据enum常量验证了登录用户组。如果登录的用户组是“Admin”,则启用“以管理员身份登录”按钮;如果登录的用户组是“NormalUser”,则启用“以普通用户身份登录”按钮。

@model CustomAuthorizationWithMVC.Models.LogInViewModel
@{
    ViewBag.Title = "LogIn";
}

LogIn Page.
@if (Model.UserGroup == Enums.UserGroups.Admin || Model.UserGroup == Enums.UserGroups.All) { Login as Administrator } @if (Model.UserGroup == Enums.UserGroups.NormalUser || Model.UserGroup == Enums.UserGroups.All) { Login as NormalUser } @if (Model.UserGroup == Enums.UserGroups.None) { Close }
Admin.cshtml

该视图将消息显示为“Admin Page”。当管理员导航到该视图时:

@{
    ViewBag.Title = "Admin";
}

Admin Page.
User.cshtml

该视图将消息显示为“User Page”。当用户导航到该视图时:

@{
    ViewBag.Title = "Admin";
}

NormalUser Page.
步骤10:运行应用程序

我只注册了“NormalUser”组。因此,启动时,我只能在“登录”页面中查看“以普通用户身份登录”按钮,如下所示:

并能够通过单击“登录”按钮导航到“普通用户页面 ”。

作为普通组的用户,我仍然可以尝试通过在浏览器中键入URL来访问“管理”页面。在这种情况下,已通过授权过滤器验证了登录用户的身份,由于我是“管理员”页面的未授权用户,因此会将我重定向回到“登录”页面,如下所示:

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0489s