如何解决安全修剪菜单作为部分视图 Menu.cshtml MenuController.cs _UsersAndRolesPartial.cshtml
我正在_Layout.cshtml文件中呈现一个菜单。仅当用户为管理员角色时,菜单的一部分才应呈现。我们在数据库中使用自定义角色。管理员字段以单个字符“ Y”或“ N”返回。它最初是一个旧版应用程序,正在迁移到MVC5。不使用LINQ或Entity Framework。
我正在将菜单创建为Menu.cshtml的部分视图:
<ul class="nav" ui-nav>
...
@if ((bool)ViewData["Admin"] == true)
{
<li>
<a href="#"><span>Users and Roles</span></a>
</li>
}
</ul>
我的_Layout.cshtml文件:
...
<aside id="aside" class="ui-aside">
@Html.Action("Menu")
</aside>
...
问题出在控制器的操作方法上。我的意图是返回一个布尔值,然后根据部分视图中的值简单地切换菜单受保护部分的呈现。现在,它在应该显示菜单的浏览器中呈现True或False,因为该布尔值是从action方法中作为HTML字符串返回的。
我知道我可以从动作方法中以字符串形式返回菜单的那一部分,但是我想避免这种情况,因为菜单中的其他部分将根据角色值进行渲染。我不想以大量的局部视图结束。如果可能的话,我也想避免使用标签助手。我只是想根据action方法中的布尔值来切换部分视图中HTML菜单部分的呈现。
操作方法:
[ChildActionOnly]
public bool Menu()
{
using (connection...)
{
...
object adminObject = command.ExecuteScalar();
if (adminObject != null)
{
string admin = adminObject.ToString();
if (admin == "Y")
ViewData["Admin"] = true;
else
ViewData["Admin"] = false;
}
}
return (bool)ViewData["Admin"];
}
解决方法
您知道Html.Action
返回MvcHtmlString
,这就是为什么它显示True
或False
您乐于尝试这样的事情吗?
_Layout.cshtml
<li>@if(Html.Action("Menu").ToString().ToLower()=="true") {
@Html.Partial("_Menu")
}</li>
局部视图
<ul class="nav" ui-nav>
<li>
<a href="#"><span>Users and Roles</span></a>
</li>
</ul>
,
您的局部视图可以声明一个附带的模型。您可以使用@Html.Action()
来
@Html.RenderAction()
将结果作为HTML字符串返回。
- 运行您的逻辑以获取当前登录用户的角色状态
- 为部分视图构建视图模型
- 将部分视图连同视图模型直接返回到响应
通过这种方式,您如何获取用户角色状态的逻辑被“封装”在子操作方法中,而显示或隐藏菜单部分的逻辑被“封装”在局部视图中。 / p>
Menu.cshtml
在菜单中,您希望呈现仅对管理员可用的部分,您可以使用@Html.RenderAction()
在buildUsersAndRoles
控制器中执行menu
动作(我刚刚做了):>
<ul class="nav" ui-nav>
...
@Html.RenderAction("buildUsersAndRoles","menu",new { area = "" })
...
</ul>
MenuController.cs
基本思想是渲染逻辑以获取所需的必要数据,包括用于显示用户是否为admin的标志。然后,基于这些,您可以确定要在视图模型内部传递的内容。
在这里,我的方法是如果用户不是admin则传递NULL,因为没有可显示的内容,否则传递包含用户和角色信息的视图模型:
public class MenuController : Controller
{
...
[ChildActionOnly]
public ActionResult BuildUsersAndRoles()
{
using (connection...)
{
...
object adminObject = command.ExecuteScalar();
if (adminObject != null)
{
string admin = adminObject.ToString();
if (admin == "Y")
{
var vm = new UsersAndRolesViewModel
{
Users = new List<...>(),Roles = new List<...>(),...
};
return PartialView("_UsersAndRolesPartial",vm);
}
}
return PartialView("_UsersAndRolesPartial");
}
}
...
}
_UsersAndRolesPartial.cshtml
最后,在仅当用户具有管理员角色时要显示的部分中,您可以使用视图模型:
@model ...UsersAndRolesViewModel
@if (Model != null)
{
<h5>Users and Roles</h5>
...
}
,
我假设单击菜单链接的操作将涉及使用asp.net授权控制访问权限来获取控制器或页面。
因此,这是我对asp.net核心的看法(它不能回答您的问题,但将来可能会很有趣)。编写标签帮助程序,以删除用户无权查看的标签。这样,您可以重新使用相同的授权策略名称来控制可见性和权限。
[HtmlTargetElement(Attributes = "policy")]
public class PolicyTagHelper : TagHelper
{
private readonly IAuthorizationService authService;
private readonly IHttpContextAccessor httpContextAccessor;
public PolicyTagHelper(IAuthorizationService authService,IHttpContextAccessor httpContextAccessor)
{
this.authService = authService;
this.httpContextAccessor = httpContextAccessor;
}
public string Policy { get; set; }
public override async Task ProcessAsync(TagHelperContext context,TagHelperOutput output)
{
if (!(await authService.AuthorizeAsync(httpContextAccessor.HttpContext.User,Policy)).Succeeded)
output.SuppressOutput();
}
}
用法;
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options => {
options.Conventions
.AuthorizePage("/UserRole","Admin");
}
services.AddAuthorization(options =>
{
options.AddPolicy("Admin",policy => ...);
}
}
<ul class="nav" ui-nav>
<li policy="Admin">
<a href="#"><span>Users and Roles</span></a>
</li>
</ul>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。