所以我创造了一个简单的'#hello world"在MVC中作为概念的证明。索引视图列出了一些记录,其后是典型的"编辑","详细信息"和"删除" ActionLinks。
但是,根据哪个AD小组拥有该记录,我不会提供其中一些选项。例如,假设我提取了5条记录,而我是Group \ Role的成员,只拥有其中的1条记录。我的索引页面看起来像......
名称价格
Foo1 $ 10.00详细信息
Foo2 $ 20.00详细信息
Foo3 $ 30.00详细信息|编辑|删除
Foo4 $ 40.00详细信息
Foo5 $ 50.00详细信息
Foo6 $ 60.00详细信息
这一切都很棒。问题是,作为用户,我只需键入/ Home / Edit / Foo1的URL,它就可以编辑访问我不拥有的记录。
在第一次搜索时,我似乎应该实现一个叫做ChildActionOnly属性的东西。根据我的阅读,听起来好像我的控制器设置为..
[ChildActionOnly]
public ActionResult Edit(string id)
{
return View(GetItem(id));
}
然后它不允许我改变我的网址并到达那里。但是,当我添加该属性时,Action Link也不再有效。
@Html.ActionLink("Edit", "Edit", new { id = item.FooName })
我知道我只是遗漏了一些东西。我已经实现了身份验证,所以除非你属于正确的角色,否则它已经阻止了对该控制器的所有访问。但是,一旦您有权访问......它并不意味着您可以更改任何内容。
答案 0 :(得分:2)
无法阻止用户尝试访问任何网址。客户端(浏览器)仅提出请求。服务器有责任确定它是否应该返回。
隐藏URL以防止访问是所谓的“默默无闻”,它基本上与完全没有安全性相同。没有什么比这更模糊,持久的用户无法弄明白。您需要真正的安全性,例如与帐户身份验证相关的角色或对象级权限。
对于记录,您正在查看对象级权限。最基本的实现涉及在对象上创建表示该对象“所有权”的对象的外键。然后,在检索对象时,另外检查当前登录的用户是否为“所有者”,如果不是,则拒绝访问。
public ActionResult Edit(int id)
{
var foo = db.Foos.Where(m => m.Id == id && m.OwnerId == User.Identity.GetUserId());
if (foo == null)
{
return new HttpNotFoundResult();
}
// do whatever for authorized user
}
答案 1 :(得分:0)
根据文件:
<强> ChildActionOnlyAttribute Class 强>
表示一个属性,用于指示仅应将操作方法作为子操作调用。
子操作方法为视图的一部分呈现内联HTML标记 而不是渲染整个视图。
可以调用任何标有
ChildActionOnlyAttribute
的方法 仅限操作或 RenderAction HTML扩展方法。有关使用属性的更多信息,请参阅。
答案 2 :(得分:0)
Nkosi对他的回答是正确的。要限制对此项的访问,您必须在Edit
操作中执行用户验证。例如:
public ActionResult Edit(string id)
{
var user = UserManager.FindById(User.Identity.GetUserId());
//Check if user can access item
}
答案 3 :(得分:0)
要获得更灵活的方法,您可以为Controller操作方法创建自定义AuthorizeAttribute
,然后将其设置为:
[MyAuthorize]
public ActionResult Edit(string id)
{
var user = UserManager.FindById(User.Identity.GetUserId());
//Check if user can access item
}
然后使用'AuthorizeAttribute`的扩展版本,您可以在那里进行检查:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
// could be used to set the AD group that you are checking for
// i.e. [MyAuthorize(strSecurityGroup="domain\group")] in the controller
public string strSecurityGroup { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var rd = httpContext.Request.RequestContext.RouteData;
var id = rd.Values["id"];
var userName = httpContext.User.Identity.Name;
//Access the current record through a DataHandler class
DataHandler dh = new DataHandler();
// Gets a field from the database that holds the username for the owner of the record
string createdBy = dh.GetCreatedBy(int.Parse(id.ToString()));
bool isAuthorized = false;
if (userName.ToString() == createdBy) isAuthorized = true;
var User = System.Web.HttpContext.Current.User;
if (User.IsInRole(@"domain\group")) isAuthorized = true;
return isAuthorized;
}
}
这就是我喜欢对AD进行授权的方式。您可以在AuthroizeAttribute中创建一个类属性,以便您也可以为每次使用该属性单独设置用户组。如果您使用授权机制来控制整个站点的操作,我认为这比每次手动执行授权检查更清晰。
答案 4 :(得分:0)
首先为过滤器创建一个类: 我们必须在操作过滤器的 OnActionExecuting 下调用此功能。
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace Customer.Filters
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PreventFromUrl : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.UrlReferrer == null ||
filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
{
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary(new { controller = "Dashboard", action = "Index", area = "" }));
}
}
}
}
然后将[PreventFromUrl]属性添加到操作或控制器的顶部:
[PreventFromUrl]
public ActionResult Index()
{
}