Asp.net mvc 如果未绑定,MVC4 Razor将释放用户ID
目前我正在MVC4中创建一些用户配置文件编辑表单,为了进行测试,我将UserId属性呈现到表单上的只读文本框中,如下所示:Asp.net mvc 如果未绑定,MVC4 Razor将释放用户ID,asp.net-mvc,data-binding,razor,model,Asp.net Mvc,Data Binding,Razor,Model,目前我正在MVC4中创建一些用户配置文件编辑表单,为了进行测试,我将UserId属性呈现到表单上的只读文本框中,如下所示: <li> @Html.LabelFor(model => model.UserId) @Html.TextBoxFor(model => model.UserId, new { @readonly="readonly"}) </li> @Html.ActionLink("Edit", "Edit", new { id=M
<li>
@Html.LabelFor(model => model.UserId)
@Html.TextBoxFor(model => model.UserId, new { @readonly="readonly"})
</li>
@Html.ActionLink("Edit", "Edit", new { id=Model.UserId })
这意味着用户ID在链接中呈现。这是安全的还是我需要重新考虑如何在UI中移动模型和ID
蒂亚
这样做安全吗
这将完成将id发送到服务器的工作。只需去掉readonly=“readonly”
属性,该属性对于隐藏输入几乎没有意义
我应该使用ViewBag进行类似的操作吗
这不会改变任何安全方面的问题。任何用户仍然可以输入他想要的任何id。无论您使用的是隐藏字段还是ActionLink,您都会将id以纯文本形式发送到服务器,任何人都可以伪造请求并放入他想要的任何id。因此,如果您的站点使用某种形式的身份验证,那么在尝试对其执行任何操作之前,您必须绝对地在服务器端检查您收到的id实际上是属于当前已验证用户的资源。否则,一些经过身份验证的用户可以提供属于另一个用户的资源的id,并能够对其进行更新。当然,这只是一个假设的场景,根本不清楚这是否是您的情况,以及是否需要保护此
id
。如果UserId是敏感的,那么还有其他选择
- 仅在会话状态下保留
服务器端(如果您的体系结构允许)UserId
- 把它放在一个盒子里。请注意,根据Darin的说法,这些可以是
HiddenFor
就可以了-将其与表单的其余部分一起发回。
不要将其放入ActionLink查询字符串中,除非这是您的路线的一部分(即/Controller/Action/id)我强烈建议使用ValueInjector。下面是一个做同样事情的代码片段
[HttpGet]
public new ActionResult Profile()
{
var model = new ProfileModel();
model.InjectFrom<UnflatLoopValueInjection>(this.GetCurrentUser());
return View(model);
}
[HttpPost]
public new ActionResult Profile(ProfileModel model)
{
if (ModelState.IsValid)
{
this.GetCurrentUser().InjectFrom<UnflatLoopValueInjection>(model);
try
{
_userService.SaveOrUpdate(this.GetCurrentUser());
TempData["Success"] = "User was successfully updated.";
return RedirectToAction("Profile");
}
catch (Exception)
{
ModelState.AddModelError("Exception", "Unexpected error");
}
}
return View(model);
}
[HttpGet]
公开新的ActionResult概要文件()
{
var模型=新的ProfileModel();
model.InjectFrom(this.GetCurrentUser());
返回视图(模型);
}
[HttpPost]
公开新的ActionResult配置文件(配置文件模型)
{
if(ModelState.IsValid)
{
this.GetCurrentUser().InjectFrom(模型);
尝试
{
_userService.SaveOrUpdate(this.GetCurrentUser());
TempData[“成功”]=“用户已成功更新。”;
返回重定向操作(“配置文件”);
}
捕获(例外)
{
AddModelError(“异常”、“意外错误”);
}
}
返回视图(模型);
}
这里是风景
@using (Html.BeginForm("Profile", "Account", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.ValidationSummary(true, "Unable to update profile. Please correct the errors and try again.", new { @class = "alert alert-block alert-error" })
@Html.EditorForModel()
<div class="form-actions">
<input type="submit" value="Update" class="btn btn-primary" />
</div>
}
@使用(Html.BeginForm(“Profile”,“Account”,FormMethod.Post,new{@class=“form horizontal”}))
{
@Html.ValidationSummary(true,“无法更新配置文件。请更正错误并重试。”,新建{@class=“alert alert block alert error”})
@Html.EditorForModel()
}
Hi Darin,id值是资源url的一部分,从Details(int-id)
方法到Edit(int-id)
方法,当单击编辑视图上的保存按钮到Update(UserProfileModel UserProfileModel)
方法时出现问题。由于Id没有绑定到Edit视图中的某个对象,因此它基本上从模型中消失了。您是否建议不要发送Id并保留该服务器端?我想得越多,就越倾向于更多地利用会话和WebSecurity.GetUserId(User.Identity.Name)
类提供的WebSecurity
方法。@Jammer,正如我在回答中已经指出的,这将取决于是否只允许当前经过身份验证的用户更新只属于他的资源。如果有人可以编辑任何资源,你不必担心。如果只有资源所有者的用户可以编辑它,您仍然可以将id保留在一个隐藏字段中,但您绝对应该在服务器上执行所有权验证。我已经在使用AutoMapper从一个对象转到另一个对象。我不确定你的答案针对的是什么问题。如果输入模型id为0,它只会覆盖IPrinciple中的id值,不是吗?您正在修改其他人的配置文件吗?还是你自己的?如果我正在编辑自己的属性,我不需要视图模型中的ID,因为我已经从原理上知道了这一点。将敏感信息放在cookie中是一种非常糟糕的方法,并且不比将其放在隐藏字段或查询字符串参数中更安全。
@using (Html.BeginForm("Profile", "Account", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.ValidationSummary(true, "Unable to update profile. Please correct the errors and try again.", new { @class = "alert alert-block alert-error" })
@Html.EditorForModel()
<div class="form-actions">
<input type="submit" value="Update" class="btn btn-primary" />
</div>
}