我正在使用UserProfile编辑页面,其中只能编辑UserProfile模型的一部分字段。许多字段仅对具有特殊角色的用户可编辑,而UserName字段当然是不可编辑和隐藏的。
现在我正考虑为所有不被用户编辑的字段包含隐藏字段,并像这样装饰我的模型:
[Table("UserProfile")]
public partial class UserProfile
{
public UserProfile()
{
webpages_Roles = new HashSet<Role>();
}
[Key]
public int UserId { get; set; }
[Required]
[StringLength(56)]
[Display(Name="Email")]
[Editable(false)] // is this the way to go?
public string UserName { get; set; }
[Required]
[Display(Name = "First name")]
[StringLength(256)]
public string FirstName { get; set; }
[Editable(false)] // is this the way to go?
public bool SomeSetting { get; set; }
// ... more properties are unimportant for this example
}
其他相关的代码:
//
// GET: /Account/Profile
public ActionResult UserProfile()
{
var userProfile = db.UserProfiles.Find(WebSecurity.CurrentUserId);
return View(userProfile);
}
//
// POST: /Account/Profile
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult UserProfile(UserProfile model)
{
// if I dont include UserName, validation will fail since it
// is now null and the field is [Required]
if (ModelState.IsValid)
{
// if I dont include hidden fields, UserId, UserName
// and SomeSetting will be null here
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
}
return View(model);
}
相关视图代码:
@Html.HiddenFor(m => m.UserId)
@Html.HiddenFor(m => m.UserName)
@Html.HiddenFor(m => m.SomeSetting)
但是,我担心通过隐藏的输入暴露这些字段。无论如何,聪明或恶意的用户都能够编辑它们吗?我知道我必须包含它们,否则在回发后属性将为null
。有人可以开导我吗?
答案 0 :(得分:1)
你可以做一些事情,比如在模型上生成一个哈希作为属性,这是连接字符串中所有值的哈希值 - 例如:
向ViewModel添加一个新属性(如果这也是您的数据库对象,则可以使用[NotMapped]注释)。:
public string SecurityHash {get;set;}
在帮助程序(或控制器)中创建一个简单的散列函数:
public string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
现在在控制器中设置哈希值:
//
// GET: /Account/Profile
public ActionResult UserProfile()
{
var userProfile = db.UserProfiles.Find(WebSecurity.CurrentUserId);
userProfile.SecurityHash = MyHashHelper.CalculateMD5Hash(userProfile.UserID + userProfile.UserName + userProfile.SomeSetting)
return View(userProfile);
}
然后在您的视图中,保留您的散列值:
@Html.HiddenFor(m => m.UserId)
@Html.HiddenFor(m => m.UserName)
@Html.HiddenFor(m => m.SomeSetting)
@Html.HiddenFor(m => m.SecurityHash)
最后,您可以在POST后检查您的值是否已被篡改购买重新散列:
//
// POST: /Account/Profile
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult UserProfile(UserProfile model)
{
string hashCheckVal = MyHashHelper.CalculateMD5Hash(model.UserID + model.UserName + model.SomeSetting)
if(string.Compare(hashCheckVal, model.SecurityHash) != 0)
{
throw new Exception("tampered with!");
}
// if I dont include UserName, validation will fail since it
// is now null and the field is [Required]
if (ModelState.IsValid)
{
// if I dont include hidden fields, UserId, UserName
// and SomeSetting will be null here
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
}
return View(model);
}
答案 1 :(得分:0)
如果您担心安全性,那么您应该在回发后从数据库中检索您的实体,然后从提交的模型更新可编辑属性。要检索模型,我认为可以将UserId保持为隐藏字段:@Html.HiddenFor(m => m.UserId)
我希望这个答案有所帮助。