/ / ASP.NET MVC: Stellen Sie sicher, dass die Artikelbearbeitung dieselbe Artikel-ID aufweist - asp.net-mvc, Validierung, Datenintegrität

ASP.NET MVC: Die Sicherstellung der Artikelbearbeitung liefert dieselbe Element-ID - asp.net-mvc, Validierung und Datenintegrität

Ich habe eine Reihe von CRUD-Seiten zum Bearbeiten eines Elements mit MVC erstellt, bin jedoch verwirrt darüber, wie ich sicherstellen kann, dass es sich bei dem Element, das ein Benutzer bearbeitet, um das gleiche Element handelt, das er zum Aktualisieren veröffentlicht.

Momentan habe ich eine HiddenFor Hilfsprogramm, das die ItemID speichert, die natürlich im Objekt bearbeiten Aktion, sein Modell auffüllend, damit ich es aktualisieren kann ...

Aber was passiert, wenn sie das bearbeiten?versteckte ID und ändern Sie es zu etwas anderem? Ich kann auf jeden Fall einen Aktionsfilter hinzufügen, um zu verhindern, dass sie ein Element bearbeiten, auf das sie keinen Zugriff haben. ABER was ist, wenn sie die ID in ein Element ändern, auf das sie Zugriff haben?

Es handelt sich nicht um einen Berechtigungsfehler, sondern um einen Datenintegritätsfehler. Ich möchte sicherstellen, dass das Element, das sie von der Website abgerufen haben BEKOMMEN für die Bearbeitung des Elements ist das gleiche, das sie POST um seinen Inhalt zu aktualisieren.

Was ist der richtige Weg, dies zu tun?

Antworten:

1 für die Antwort № 1

Wenn sie Zugang dazu haben, sind sie im Grunde genommen"Hacken Sie Ihre Anwendung", um etwas zu tun, was sie bereits über eine GUI tun können (angeblich ...). Im Grunde wäre es das Gleiche wie der Versuch, dieses andere Element zu bearbeiten. Und wenn jemand den Quellcode auf der Client-Seite ändert, können in der Tat seltsame Dinge passieren.

Natürlich sollte es serverseitigen Zugriff gebenKontrolle und Validierung, so dass alle ungültigen Daten abgelehnt werden. Aber wenn alles, was sie weitergeben, gültig ist, warum sollten sie es dann nicht können? Es gibt nicht wirklich viel, was man tun kann. Eine Anfrage ist eine Anfrage - wenn sie gültig ist, ist sie gültig. Egal woher sie kommt.

Was ist, wenn ich eine Anfrage in einer Software wie Fiddler erstelle? Dann kann ich meine Daten ändern, ohne Ihre Webanwendung zu sehen - und überhaupt nichts "bearbeiten".


0 für die Antwort № 2

Ich könnte zu spät sein, um diese Frage zu beantworten, und ich stehe vor demselben Problem und habe dieses Problem auf folgende Weise vermieden.

  1. Wie Sie sagten, haben Sie ItemId und während der PostJemand ändert ItemId in einen anderen Wert, damit er einen anderen Artikel überschreiben kann, da dieser Benutzer die Berechtigung hat, diesen Artikel ebenfalls zu bearbeiten. Um dieses Problem zu vermeiden, denke ich, dass basierend auf ItemId eine ID generiert wird, die weniger vorhersehbar ist (wie der Hash-Wert der Item-ID und dieser Hash basiert auf dem Schlüssel, sodass jede Seite Ihrer Anwendung einen anderen Schlüssel hat, sodass, wenn itemid gleich ist, auch dieser generiert wird anderer Hashwert).

  2. Jetzt beim Formular posten. Holen Sie sich zuerst ItemId und holen Sie sich den Hash-Wert basierend auf dem Schlüssel und vergleichen Sie ihn mit dem zuvor generierten Wert. Wenn der Vergleich fehlschlägt, können Sie entweder ItemId oder Hash-Wert verwenden und wir erhalten eine Fail-Anfrage.

Hier ist das kleine Beispiel.

public static class HtmlHelperExtentions
{
public static MvcHtmlString GenerateIntegrityToken(this HtmlHelper htmlHelper,
string name , string valuefromwhichtokengenerate , string key)
{
var builder = new TagBuilder("input");
builder.MergeAttribute("type", "hidden");
builder.MergeAttribute("name", "DataIntegrity_" + name);
builder.MergeAttribute("value", DataIntegrityHelper.GetTokenValue(valuefromwhichtokengenerate,key));
return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
}
}

public static class DataIntegrityHelper
{
public static bool IsValid(string value,string encryptedvalue,string key)
{
string tempEncryptedValue = GetTokenValue(value, key);
return string.Equals(tempEncryptedValue,encryptedvalue,StringComparison.InvariantCultureIgnoreCase);
}

public static string GetTokenValue(string value, string key)
{
if (string.IsNullOrEmpty(key))
key = "MVCTokenForDataIntigrity4@5#6";
else
key = "1@2#3" + key;
byte[] keys = System.Text.UTF8Encoding.UTF8.GetBytes(key);
byte[] messageBytes = System.Text.UTF8Encoding.UTF8.GetBytes(value);
HMAC mac = HMACSHA256.Create();
mac.Key = keys;
byte[] hashBytes = mac.ComputeHash(messageBytes);
return ByteToString(hashBytes);
}

public static string ByteToString(byte[] buff)
{
string sbinary = "";

for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
}

Beispiel Personenmodell.

public class Person
{
public int Id { get; set; }
public string DataIntegrity_Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

In Ansicht (person.cshtml)

@using (Html.BeginForm())
{
@Html.GenerateIntegrityToken("Id",Model.Id.ToString(),"Hello")
@Html.HiddenFor(cc=>cc.Id)
<br />
@Html.TextBoxFor(cc=>cc.FirstName)
<br />
@Html.TextBoxFor(cc => cc.LastName)
<br />
<input type="submit" />
}

Controller-Aktionen

 public ActionResult Person()
{
return View(new Person());
}

[HttpPost]
public ActionResult Person(Person person)
{
if (Extentions.DataIntegrityHelper.IsValid(person.Id.ToString(), person.DataIntegrity_Id, "Hello"))
{
return View(person);
}
else
{
return Content("Data integrity validation fails.");
}
}