User Tools

Site Tools


technology:domainmodel:command:commanduniqueness

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

technology:domainmodel:command:commanduniqueness [2013/02/06 11:11]
rtavassoli [Befehlseindeutigkeit]
technology:domainmodel:command:commanduniqueness [2013/02/06 11:34] (current)
rtavassoli
Line 16: Line 16:
 Ich meine, man kann komplexere Lösungen bauen, die kaum etwas zusätzliches kosten, das System aber noch robuster machen((Murphys Gesetz sagt ja, dass, wenn etwas schief läuft, es so richtig schief läuft - frei gedeutet)). Für mich gilt somit erstens Ich meine, man kann komplexere Lösungen bauen, die kaum etwas zusätzliches kosten, das System aber noch robuster machen((Murphys Gesetz sagt ja, dass, wenn etwas schief läuft, es so richtig schief läuft - frei gedeutet)). Für mich gilt somit erstens
 > Ein Befehl wird nicht nur über die ID identifiziert, sondern auch über den authentifizierten Absender. Es wird dann darauf vertraut, dass der Absender darauf achtet, dass //seine// Befehle eine eindeutige ID erhalten. Da die Idempotenz-ID eine Kombination aus dem Absender und der vom Absender erzeugten ID ist, wäre der Befehl global eindeutig. > Ein Befehl wird nicht nur über die ID identifiziert, sondern auch über den authentifizierten Absender. Es wird dann darauf vertraut, dass der Absender darauf achtet, dass //seine// Befehle eine eindeutige ID erhalten. Da die Idempotenz-ID eine Kombination aus dem Absender und der vom Absender erzeugten ID ist, wäre der Befehl global eindeutig.
-Wenn die ID auch noch frei konfigurierbar ist((ein ausreichend großer String)), dann sind alle Systemanforderungen für eine fast lückenlose Sicherheit gegeben((vorausgesetzt, dass System wird nicht gehackt)). 
 === Wer ist verantwortlich === === Wer ist verantwortlich ===
 Wenn ich als Client eindeutige Befehle versende, möchte ich davon ausgehen können, dass sie auch als solche erkannt werden. Ich kann mich dabei nicht darauf verlassen, dass sich alle Clients korrekt verhalten, vor allem dann nicht, wenn die Clients nicht alle aus einer Hand kommen. Daher ist der Server dafür verantwortlich, das Verhalten der Clients zu überprüfen. Dafür muss der Server dem Client vertrauen können. Die erste Regel ist somit Wenn ich als Client eindeutige Befehle versende, möchte ich davon ausgehen können, dass sie auch als solche erkannt werden. Ich kann mich dabei nicht darauf verlassen, dass sich alle Clients korrekt verhalten, vor allem dann nicht, wenn die Clients nicht alle aus einer Hand kommen. Daher ist der Server dafür verantwortlich, das Verhalten der Clients zu überprüfen. Dafür muss der Server dem Client vertrauen können. Die erste Regel ist somit
 > Der Server akzeptiert idempotente Befehle nur von Clients, die vom Server identifiziert werden können. > Der Server akzeptiert idempotente Befehle nur von Clients, die vom Server identifiziert werden können.
 Das macht man entweder, indem sich der Client gegen den Server authentifiziert, z.B. über ein Zertifikat. Das klappt aber nicht, wenn die Befehle über einen Bus versendet werden. Das macht man entweder, indem sich der Client gegen den Server authentifiziert, z.B. über ein Zertifikat. Das klappt aber nicht, wenn die Befehle über einen Bus versendet werden.
-Alternativ kann man das über die mit gesendeten Authentifizierungsdaten des Users machen. Wenn man sicher sein kann, dass nur ein bestimmter Client die Daten eines bestimmten Users kennt, dann kann sich der Client darüber dem Server gegenüber identifizieren. Eine Saga kann z.B. ein bestimmtes Systemkonto verwenden, dessen Anmeldedaten nur der Saga bekannt sind. Kommt ein Befehl mit den Anmeldedaten dieses Kontos, kann der Server davon ausgehen, dass der Befehl von der Saga kommt.+Alternativ kann man das über die mit gesendeten Authentifizierungsdaten des Users machen. Wenn man sicher sein kann, dass nur ein bestimmter Client die Anmeldedaten eines bestimmten Users kennt, dann kann sich der Client darüber dem Server gegenüber identifizieren. Eine Saga kann z.B. ein bestimmtes Systemkonto verwenden, dessen Anmeldedaten nur der Saga bekannt sind. Kommt ein Befehl mit den Anmeldedaten dieses Kontos an, kann der Server davon ausgehen, dass der Befehl von der Saga kommt.
 \\ \\ \\ \\
-Wenn diverse Clients gebaut werden, und das von unterschiedlichen, unabhängigen Firmen, kann es durchaus sein, dass der Algorithmus für die Erzeugung der IDs, die die Firmen für die Befehlseindeutigkeit verwenden, mehrfach verwendet wird. Es reicht also nicht aus, dass der Server nur idempotente Befehle von authentifizierten Clients akzeptiert. Es gilt somit: +Wenn diverse Clients gebaut werden, und das von unterschiedlichen, unabhängigen Firmen, kann es durchaus sein, dass der Algorithmus für die Erzeugung der IDs, die die Firmen für die Befehlseindeutigkeit verwenden, mehrfach verwendet wird. Zwei Clients könnten eine identische ID erzeugen. Auch wenn der Server den beiden vertraut, kann es so zu unbeabsichtigten Konflikten kommen. Es reicht also nicht aus, dass der Server nur idempotente Befehle von authentifizierten Clients akzeptiert. Es gilt zusätzlich 
-> Damit die Firmen ihre Algorithmen nicht koordinieren müssen, muss ein Teil der Idempotenz-ID die Anmeldedaten des Kontos enthalten, gemeinsam mit einer Kennung der verwendeten Authentifizierungsmethode. +> Damit die Firmen ihre Algorithmen nicht koordinieren müssen, muss ein Teil der Idempotenz-ID die Identität des Absenders enthalten, gemeinsam mit einer Kennung der verwendeten Authentifizierungsmethode. 
-Angenommen, ich verwende eine simple Benutzername|Passwort Authentifizierung. PRO•M hat für diese Authentifizierungsmethode die Kennung //UN//((für UserName)) vergeben. Ich bin eine Saga, die Order importiert. Die Saga kann auf unterschiedlichen Partitionen laufen, läuft immer im Kontext des Kontos, das durch den Benutzername //OrderImportSagaAccount// identifiziert wird. Jede Partition erhält eine eigene Partitions-ID, z.B. //P1//. Nun kann jede Saga auf jeder Partition eindeutige IDs erzeugen, z.B. indem ein einfacher Zähler verwendet wird. Die zusammengesetzte ID ist dann global eindeutig. Angenommen, der Zähler ist bei 5547. Meine eindeutige ID wäre dann+Angenommen, ich verwende eine simple Benutzername|Passwort Authentifizierung. PRO•M hat für diese Authentifizierungsmethode die Kennung //UN//((für UserName)) vergeben. Ich bin eine Saga, die Aufträge importiert. Die Saga hat ein eigenes Benutzerkonto //OrderImportSagaAccount//, kann sich also mit dem Konto gegen den Server identifizieren. Die Saga kann auf unterschiedlichen Partitionen laufen, läuft immer im Kontext des Kontos, das durch den Benutzername //OrderImportSagaAccount// identifiziert wird. Jede Partition erhält eine eigene Partitions-ID, z.B. //P1//. Nun kann jede Saga auf jeder Partition eindeutige IDs erzeugen, z.B. indem ein einfacher Zähler verwendet wird. Die zusammengesetzte ID ist dann global eindeutig. Angenommen, der Zähler ist bei 5547. Meine eindeutige ID wäre dann
 > 5547_P1#OrderImportSagaAccount@UN > 5547_P1#OrderImportSagaAccount@UN
 Die eindeutige Identifizierung der Saga läuft über das Konto. Der Server analysiert die ID, sieht, dass //UN = Username// zur Identifizierung verwendet werden soll, und prüft, ob das mit dem Typ der mitgesendeten Authentifizierungsdaten übereinstimmt((# und @ sind dabei reservierte Zeichen und dürfen nicht woanders in der ID vorkommen. Wenn doch, wird der Befehl mit einer InvalidIdempotencyIdException abgelehnt)). Dann erkennt der Server, dass der Benutzername //OrderImportSagaAccount// sein soll, und vergleicht das mit dem Inhalt der mitgesendeten Authentifizierungsdaten((nachdem die Daten erfolgreich authentifiziert wurden)). Wenn alles stimmt, wird die ID als global eindeutig akzeptiert. Die eindeutige Identifizierung der Saga läuft über das Konto. Der Server analysiert die ID, sieht, dass //UN = Username// zur Identifizierung verwendet werden soll, und prüft, ob das mit dem Typ der mitgesendeten Authentifizierungsdaten übereinstimmt((# und @ sind dabei reservierte Zeichen und dürfen nicht woanders in der ID vorkommen. Wenn doch, wird der Befehl mit einer InvalidIdempotencyIdException abgelehnt)). Dann erkennt der Server, dass der Benutzername //OrderImportSagaAccount// sein soll, und vergleicht das mit dem Inhalt der mitgesendeten Authentifizierungsdaten((nachdem die Daten erfolgreich authentifiziert wurden)). Wenn alles stimmt, wird die ID als global eindeutig akzeptiert.
Line 37: Line 36:
 In dem oben beschriebenen Mechanismus werden die ersten beiden Punkte berücksichtigt. Wenn man davon ausgeht, dass die Kennung vom Versender eindeutig erzeugt wird, braucht man den Inhalt und Zeitstempel nicht mehr vergleichen. Man könnte das noch machen, und eine DuplicateIdempotencyIdException auslösen wenn eine Idempotenz-ID ankommt, die bereits erhalten wurde, deren Inhalt aber ein anderer war. Das wäre aber übertrieben, bzw. kann auch immer noch dazu gebaut werden. In dem oben beschriebenen Mechanismus werden die ersten beiden Punkte berücksichtigt. Wenn man davon ausgeht, dass die Kennung vom Versender eindeutig erzeugt wird, braucht man den Inhalt und Zeitstempel nicht mehr vergleichen. Man könnte das noch machen, und eine DuplicateIdempotencyIdException auslösen wenn eine Idempotenz-ID ankommt, die bereits erhalten wurde, deren Inhalt aber ein anderer war. Das wäre aber übertrieben, bzw. kann auch immer noch dazu gebaut werden.
 === Beispiel Endanwender === === Beispiel Endanwender ===
-Wenn ein Endanwender einen Befehl absendet, braucht es i.d.R. gar keine Idempotenz-ID. Wenn man aber z.B. einbaut, dass sich die Client Anwendung die gesendeten Befehle merkt, damit nach einem unerwarteten Fehler und einem Neustart geprüft werden kann, was mit dem Befehl passiert ist((erhalten, ausgeführt?)), kann der Client eine Befehls-ID schreiben. Damit das einfach bleibt, sollte der Client einfach eine GUID verwenden, vielleicht gemeinsam mit einem Zeitstempel((und wie für jede ID gefordert mit der Identität des angemeldeten Users.+Wenn ein Endanwender einen Befehl absendet, braucht es i.d.R. gar keine Idempotenz-ID. Wenn man aber z.B. einbaut, dass sich die Client Anwendung die gesendeten Befehle merkt, damit nach einem unerwarteten Fehler und einem Neustart geprüft werden kann, was mit dem Befehl passiert ist((erhalten, ausgeführt?)), kann der Client eine Befehls-ID schreiben. Damit das einfach bleibt, sollte der Client einfach eine GUID verwenden, vielleicht gemeinsam mit einem Zeitstempel((und wie für jede ID gefordert mit der Identität des angemeldeten Users)).
 \\ \\ \\ \\
 Für Systemagenten((Sagas, Event Handler)) ist die Eindeutigkeit Pflicht, weil die schließliche Konsistenz und auch die Synchronisierung mit anderen Systemen davon abhängt. Die Sicherheit ist vollständig gegeben, solange das Konto nicht gehackt wird, das von den Systemagenten verwendet wird. Für einen Endanwender wird es i.d.R. gar nicht notwendig sein, eine eindeutige ID zu setzen. Wenn doch, gibt es auch noch andere Methoden, das sicher zu machen, z.B. indem man dem Konto TANs gibt, und der Anwender für idempotente Befehle die TANs verwendet. Für Systemagenten((Sagas, Event Handler)) ist die Eindeutigkeit Pflicht, weil die schließliche Konsistenz und auch die Synchronisierung mit anderen Systemen davon abhängt. Die Sicherheit ist vollständig gegeben, solange das Konto nicht gehackt wird, das von den Systemagenten verwendet wird. Für einen Endanwender wird es i.d.R. gar nicht notwendig sein, eine eindeutige ID zu setzen. Wenn doch, gibt es auch noch andere Methoden, das sicher zu machen, z.B. indem man dem Konto TANs gibt, und der Anwender für idempotente Befehle die TANs verwendet.
technology/domainmodel/command/commanduniqueness.1360145511.txt.gz · Last modified: 2013/02/06 11:11 by rtavassoli