对于asp.net MVC 3微小的自定义角色管理 [英] tiny custom role management for asp.net mvc 3

查看:170
本文介绍了对于asp.net MVC 3微小的自定义角色管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我选择了做asp.net MVC3学校的项目和有需要用户/角色的管理。我认为会员附带asp.net是太大了一所学校的工程中的。
所以我的想法是这样的。如果我能找到的Zend predispatch的为ASP,甚至一个更好的我可以存储为特权一个角色可访问的网址,并在会议上加载它等效方法和检查是否有特定的用户可以访问它,如果不重定向。

我的问题是这样的:

是否有ASP preDispatch 方法的任何等同?结果
是否有我的问题的更好的办法?如果是,请上传资源

感谢您阅读本

修改
我生成使用这个来自DATABSE sublinks:

 公共静态类SubMenuHelper
{
    公共静态MvcHtmlString GetSubMenu()
    {
        变种DB =新SchoolContextEx preSS();
        VAR子从s在db.Disciplines选择S =;
        VAR sbuilder =新的StringBuilder();
        的foreach(以子菜单VAR学科)
        {
            sbuilder.AppendFormat(<李><一类='SUBLINKHREF =/学科/细节/ {0}> {1}< / A>< /李>中,discipline.DisciplineID, discipline.Name);
        }
        返回新MvcHtmlString(sbuilder.ToString());
    }
}


解决方案

您可以实现这个样子。


  1. 枚举的角色

  2. FilterAttribute

  3. 菜单创建Web.sitemap中

  4. 添加菜单制作动作

  5. 添加菜单_Layout.cshtml

  6. 添加到FilterAttribute控制器或行动

---- 1枚举------

 公共枚举角色{
     常见= 1,
     学生= 2,
     教师= 4
     管理= 8
}

---- 2 RequirePermissionFilter ----

 公共类RequirePermissionFilter:ActionFilterAttribute,个IAuthorizationFilter
{      私人只读角色[] _requiredRoles;
       公共RequirePermissionFilter(角色requiredRoles)
    {
        _requiredRoles =新角色[] {} requiredRoles;
    }    公共RequirePermissionFilter(角色[] requiredRoles)
    {
        _requiredRoles = requiredRoles;
    }
    公共无效OnAuthorization(AuthorizationContext filterContext)
    {
        VAR成功= FALSE;        的foreach(角色在_requiredRoles角色)
        {
             成功| = _authManager.HasPermission(作用);
        }        如果(成功)
        {
            VAR缓存= filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(新的TimeSpan(0));
            cache.AddValidationCallback((HttpContext的背景下,对象数据,参考HttpValidationStatus validationStatus)=>
            {
                validationStatus = this.OnCacheAuthorization(新HttpContextWrapper(上下文));
            }, 空值);
        }
        其他
        {
            this.HandleUnauthorizedRequest(filterContext);
        }
    }
    私人无效HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // Ajax请求将返回状态code 500,因为我们不希望返回的结果
        //重定向到登录页面。
        如果(filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result =新的HTTPStatus codeResult(500);
        }
        其他
        {
            filterContext.Result =新RedirectToRouteResult(错误 - 401,NULL);
        }
    }
    公共HttpValidationStatus OnCacheAuthorization(HttpContextBase的HttpContext)
    {
        VAR成功= FALSE;        的foreach(角色在_requiredRoles角色)
        {
            成功| = _authManager.HasPermission(作用);
        }        如果(成功)
        {
            返回HttpValidationStatus.Valid;
        }
        其他
        {
            返回HttpValidationStatus.IgnoreThisRequest;
        }
    }
}

---- 3 Web.sitemap中-----

 <?XML版本=1.0编码=UTF-8&GT?;
<站点地图的xmlns =htt​​p://schemas.microsoft.com/AspNet/SiteMap-File-1.0>
    <的SiteMapNode URL =角色名=标题=menuVisible =真>
        <的SiteMapNode URL =〜/首页/索引角色名= - 1称号=家menuVisible =真/>
        <的SiteMapNode URL =〜/学生/索引角色名=2 TITLE =学生menuVisible =真>
             <的SiteMapNode URL =〜/ MyLessons /索引角色名=2标题=我的课程menuVisible =真/>
        < /&的SiteMapNode GT;
        <的SiteMapNode URL =〜/教师/索引角色名=4标题=老师menuVisible =真/>
        <的SiteMapNode URL =〜/行政/索引角色名=8标题=管理menuVisible =真/>
    < /&的SiteMapNode GT;
< /网站地图>

---- 4菜单造物主行动----

 公共类CommonController:控制器{    公众的ActionResult NavigationMenu()
        {
            返回含量(SiteMapMenu());
        }
        公共字符串SiteMapMenu()
        {
            StringBuilder的SB =新的StringBuilder();
            sb.Append(< D​​IV CLASS ='菜单'>< UL>中);
            VAR topLevelNodes = SiteMap.RootNode.ChildNodes;
            的foreach(在topLevelNodes的SiteMapNode节点)
            {
                如果(HasPermission(节点)及&放大器; ISVISIBLE(节点))
                {
                    如果(SiteMap.CurrentNode ==节点)
                        sb.Append(<李类='selectedMenuItem'>中);
                    其他
                        sb.Append(<立GT;);                    如果(!string.IsNullOrEmpty(node.Url))
                        sb.AppendFormat(&下; A HREF ={0}> {1}&下; / A>中,Url.Content(node.Url),node.Title);
                    其他
                        sb.AppendFormat(&下; A HREF ='的javascript:无效(0)'> {0}&下; / A>中,node.Title);
                    如果(node.HasChildNodes&放大器;&放大器; AnyOfChildIsVisible(节点))
                    {                        的foreach(的SiteMapNode childNode在node.ChildNodes)
                        {
                            如果(HasPermission(childNode)及&放大器; ISVISIBLE(childNode))
                            {
                                sb.Append(<立GT;);
                                sb.AppendFormat(&下; A HREF ={0}> {1}&下; / A>中,Url.Content(childNode.Url),childNode.Title);
                                sb.Append(< /李>);
                            }
                        }                        sb.Append(< / UL>< / DIV>中);
                    }                    sb.AppendLine(< /李>);
                }
            }
            sb.AppendLine(< / UL>< / DIV>中);
            返回sb.ToString();
        }
        私人布尔HasPermission(的SiteMapNode节点)
        {
            INT角色名= int.Parse(节点[角色名]的ToString());
            如果((角色名== -1)||(_authManager.HasPermission((角色)角色名)))
                返回true;
            返回false;
        }
        私人布尔可见性(的SiteMapNode节点)
        {
            返回bool.Parse(节点[menuVisible]);
        }        私人布尔AnyOfChildIsVisible(的SiteMapNode节点)
        {
            的foreach(在node.ChildNodes的SiteMapNode项)
            {
                如果(ISVISIBLE(项目))
                    返回true;
            }
            返回false;
        }
}

---- 5添加帮手_Layout.cshtml

  @ Html.Action(NavigationMenu,通用)

---- 6控制器----

  [RequirePermissionFilter(Roles.Student)
公共类StudentController:控制器{
   / *
    *
    *
    *
    *
    * /}

---- AuthManager ---

 公共接口IAuthManager
{
    布尔HasPermission(角色requiredRole);
}公共类AuthManager:IAuthManager
{
    私人ISessionManager _sessionManager;
    私人ISuggestionConfig _config;    公共BOOL HasPermission(角色requiredRoles)
    {
        如果(HttpContext.Current.Session [USER]!= NULL)
            回报(requiredRoles&放大器;((用户)HttpContext.Current.Session [USER])角色)== requiredRoles;
        其他
            返回false;
    }
}

I chose to do a school project with asp.net mvc3 and there is a need of a user/role management. I think the membership that ships with asp.net is way too big for a school projec. SO my thought is this. if i could find an equivalent of Zend predispatch method for asp or even a better one i could store the urls accessible as privilege for a role and load it in session and check if a particular user have access to it and redirect if not.

my question are this:

Is there any equivalent of PreDispatch method in asp?
Is there any better approach for my problem ? if yes please post resources

Thanks for reading this

EDIT i generate sublinks from databse using this:

 public static class SubMenuHelper
{


    public static MvcHtmlString GetSubMenu()
    {
        var db = new SchoolContextExpress();
        var submenu = from s in db.Disciplines select s;
        var sbuilder = new StringBuilder();
        foreach (var discipline in submenu)
        {
            sbuilder.AppendFormat("<li><a class='sublink' href='/Discipline/Details/{0}'>{1}</a></li>", discipline.DisciplineID, discipline.Name);
        }
        return new MvcHtmlString(sbuilder.ToString());
    }
}

解决方案

You can implement like this.

  1. Enum for roles
  2. FilterAttribute
  3. Create Web.sitemap for menu
  4. Add Menu creator action
  5. Add Menu to _Layout.cshtml
  6. Add FilterAttribute to controller or action

----1 Enum------

public enum Roles{
     Common=1,
     Student = 2,
     Teacher=4
     Administration=8
}

----2 RequirePermissionFilter----

public class RequirePermissionFilter : ActionFilterAttribute, IAuthorizationFilter
{

      private readonly Roles[] _requiredRoles;
       public RequirePermissionFilter(Roles requiredRoles)
    {
        _requiredRoles = new Roles[] { requiredRoles };
    }

    public RequirePermissionFilter(Roles[] requiredRoles)
    {
        _requiredRoles = requiredRoles;
    }
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var success = false;

        foreach (Roles role in _requiredRoles)
        {
             success |= _authManager.HasPermission(role);
        }

        if (success)
        {
            var cache = filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(new TimeSpan(0));
            cache.AddValidationCallback((HttpContext context, object data, ref HttpValidationStatus validationStatus) =>
            {
                validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
            }, null);
        }
        else
        {
            this.HandleUnauthorizedRequest(filterContext);
        }
    }
    private void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // Ajax requests will return status code 500 because we don't want to return the result of the
        // redirect to the login page.
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new HttpStatusCodeResult(500);
        }
        else
        {
            filterContext.Result = new RedirectToRouteResult("Error - 401", null);
        }
    }
    public HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        var success = false;

        foreach (Roles role in _requiredRoles)
        {
            success |= _authManager.HasPermission(role);
        }

        if (success)
        {
            return HttpValidationStatus.Valid;
        }
        else
        {
            return HttpValidationStatus.IgnoreThisRequest;
        }
    }
}

----3 Web.sitemap-----

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="" roleName="" title="" menuVisible="True">
        <siteMapNode url="~/Home/Index" roleName="-1" title="Home" menuVisible="True"/>
        <siteMapNode url="~/Student/Index" roleName="2 title="Student" menuVisible="True">
             <siteMapNode url="~/MyLessons/Index" roleName="2 title="My Lessons" menuVisible="True"/>
        </siteMapNode>
        <siteMapNode url="~/Teacher/Index" roleName="4 title="Teacher" menuVisible="True"/>
        <siteMapNode url="~/Administration/Index" roleName="8 title="Administration" menuVisible="True"/>
    </siteMapNode>
</siteMap>

----4 Menu Creator Action----

public class CommonController : Controller{

    public ActionResult NavigationMenu()
        {
            return Content(SiteMapMenu());
        }
        public string SiteMapMenu()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div class='menu'><ul>");
            var topLevelNodes = SiteMap.RootNode.ChildNodes;


            foreach (SiteMapNode node in topLevelNodes)
            {
                if (HasPermission(node) && IsVisible(node))
                {
                    if (SiteMap.CurrentNode == node)
                        sb.Append("<li class='selectedMenuItem'>");
                    else
                        sb.Append("<li>");

                    if (!string.IsNullOrEmpty(node.Url))
                        sb.AppendFormat("<a href='{0}'>{1}</a>", Url.Content(node.Url), node.Title);
                    else
                        sb.AppendFormat("<a href='javascript:void(0)'>{0}</a>", node.Title);
                    if (node.HasChildNodes && AnyOfChildIsVisible(node))
                    {

                        foreach (SiteMapNode childNode in node.ChildNodes)
                        {
                            if (HasPermission(childNode) && IsVisible(childNode))
                            {
                                sb.Append("<li>");
                                sb.AppendFormat("<a href='{0}'>{1}</a>", Url.Content(childNode.Url), childNode.Title);
                                sb.Append("</li>");
                            }
                        }

                        sb.Append("</ul></div>");
                    }

                    sb.AppendLine("</li>");
                }
            }
            sb.AppendLine("</ul></div>");
            return sb.ToString();
        }
        private bool HasPermission(SiteMapNode node)
        {
            int roleName = int.Parse(node["roleName"].ToString());
            if ((roleName == -1) || (_authManager.HasPermission((Roles)roleName)))
                return true;
            return false;
        }
        private bool IsVisible(SiteMapNode node)
        {
            return bool.Parse(node["menuVisible"]);
        }

        private bool AnyOfChildIsVisible(SiteMapNode node)
        {
            foreach (SiteMapNode item in node.ChildNodes)
            {
                if (IsVisible(item))
                    return true;
            }
            return false;
        }
}

----5 Add helper to _Layout.cshtml

  @Html.Action("NavigationMenu", "Common")

----6 Controller----

[RequirePermissionFilter(Roles.Student)]
public class StudentController : Controller{
   /*
    *
    *
    *
    *
    */

}

----AuthManager---

public interface IAuthManager
{


    bool HasPermission(Roles requiredRole);
}

public class AuthManager : IAuthManager
{
    private ISessionManager _sessionManager;
    private ISuggestionConfig _config;

    public bool HasPermission(Roles requiredRoles)
    {
        if (HttpContext.Current.Session["USER"] != null)
            return (requiredRoles & ((User)HttpContext.Current.Session["USER"]).Roles) == requiredRoles;
        else
            return false;
    }
}

这篇关于对于asp.net MVC 3微小的自定义角色管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆