对于asp.net MVC 3微小的自定义角色管理 [英] tiny custom role management for 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());
}
}
您可以实现这个样子。
- 枚举的角色
- FilterAttribute
- 菜单创建Web.sitemap中
- 添加菜单制作动作
- 添加菜单_Layout.cshtml
- 添加到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 =http://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(< DIV 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.
- Enum for roles
- FilterAttribute
- Create Web.sitemap for menu
- Add Menu creator action
- Add Menu to _Layout.cshtml
- 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屋!