Power Pages Server Logic: React und Dataverse sicher verbinden
Power Pages Server Logic prüft Browserdaten, Request-Größe, Autorisierung und OData-Filter, bevor React die Dataverse Custom API erreicht.
Inhalt
- Warum Browserdaten in Power Pages keine Autorisierung ersetzen
- Welche Prüfungen übernimmt React in der Power Pages Suche?
- Wie schützt ein CSRF-Token Requests an Power Pages Server Logic?
- Wie begrenzt Power Pages Server Logic Request-Größe und Operationen?
- Wie leitet Power Pages Server Logic Autorisierung ab?
- Wie validiert Power Pages Server Logic Suchfilter?
- Wie erzeugt Power Pages Server Logic sichere OData-Filter?
- Wie protokolliert Power Pages Server Logic ohne Suchdaten?
- Warum müssen Fehler in Power Pages Server Logic sichtbar bleiben?
- Welche Sicherheitsgrenzen ergänzt Power Pages Server Logic?
- Power Pages Server Logic Sicherheitsgrenze: Erfahrungen aus dem Projekt
Warum Browserdaten in Power Pages keine Autorisierung ersetzen
Ein React Formular kann jeden Filter prüfen. Es kann ungültige Werte blockieren, Zahlen begrenzen und nur bekannte Optionen anzeigen.
Der Browser bleibt trotzdem veränderbar.
Ein Portalnutzer kann den Request in den DevTools bearbeiten. Ein anderes Skript kann die React Anwendung umgehen. Ein direkter HTTP Request braucht die Formularlogik überhaupt nicht.
Ein manipulierter Body könnte zum Beispiel so aussehen:
{
"operation": "search",
"searchText": "Berlin",
"isauthorized": true,
"objectfilter": "$filter=untrusted expression"
}Wenn der Server diese Werte direkt übernimmt, ist die clientseitige Validierung nur eine Bedienhilfe. Sie bildet keine Sicherheitsgrenze.
In meiner Enterprise-Suche darf der Browser deshalb weder die Autorisierung noch fertige OData Ausdrücke bestimmen. Power Pages Server Logic liest den Request als nicht vertrauenswürdige Eingabe und baut daraus einen neuen kontrollierten Dataverse Vertrag.
Power Pages Server Logic Sicherheit bedeutet für mich zuerst eine klare Vertrauensgrenze. Die Architekturübersicht der Power Pages Enterprise-Suche zeigt, wo diese Grenze im vollständigen Datenfluss liegt.
Welche Prüfungen übernimmt React in der Power Pages Suche?
Ich prüfe Filter bereits in React. Das Suchfeld besitzt eine Maximallänge. Optionswerte kommen aus einem bekannten Katalog. Zahlen werden gegen ihre fachlichen Bereiche geprüft.
Diese Regeln liefern schnelle Rückmeldungen und saubere URLs. Sie verhindern unnötige Requests.
Sie bleiben aber wiederholbar.
Server Logic prüft dieselben relevanten Grenzen unabhängig vom Browser. Ein gültiger React Request und ein direkt formulierter Request durchlaufen denselben serverseitigen Vertrag.
Diese Trennung beginnt schon beim zentralen React Host und seiner JSON-Konfiguration. Der Host kontrolliert, wie das Widget startet. Server Logic kontrolliert, welche Browserdaten den Backend Vertrag beeinflussen dürfen.
Aufgabe | React | Server Logic | Dataverse Custom API |
|---|---|---|---|
Eingaben prüfen | Schnelle Rückmeldung und saubere URLs | Verbindliche Prüfung aller relevanten Grenzen | Erwartet kontrollierte Parameter |
Autorisierung | Keine Entscheidung | Leitet Nutzerstatus aus Portalsitzung ab | Wendet fachlichen Vertrag an |
OData Filter | Sendet nur Filterwerte | Baut feste Ausdrücke aus akzeptierten Werten | Erhält serverseitig erzeugte Filter |
Fehlerbehandlung | Zeigt technischen Fehler oder Ergebniszustand | Meldet Vertragsfehler sichtbar | Liefert definierten Status und Body |
Wie schützt ein CSRF-Token Requests an Power Pages Server Logic?
Microsoft verlangt für clientseitige Aufrufe von Server Logic einen Cross-Site Request Forgery Token.
Die Dokumentation zum Aufruf von Power Pages Server Logic verwendet dafür shell.safeAjax.
Im bestehenden Portal stellt die bereits geladene Power Pages Abhängigkeit einen Wrapper als webapi.safeAjax bereit. Der Transport Adapter nutzt genau diese zentrale Funktion:
function postServerLogicRequest(request: ServerLogicRequest): Promise<string> {
return new Promise((resolve, reject) => {
const webapi = window.webapi;
if (webapi === undefined) {
reject(new Error('Power Pages webapi.safeAjax is unavailable.'));
return;
}
webapi.safeAjax({
type: 'POST',
url: '/_api/serverlogics/catalog-search',
contentType: 'application/json',
data: JSON.stringify(request),
success: (response) => {
if (response.success !== true) {
reject(new Error('Server Logic returned an unsuccessful response.'));
return;
}
resolve(response.data);
},
error: (error) => {
reject(new Error(error.responseJSON?.error?.message ?? 'Server Logic request failed.'));
},
});
});
}Der Wrapper ergänzt den Schutz gegen gefälschte Requests aus einem fremden Seitenkontext. Die Microsoft Dokumentation zum CSRF Wrapper zeigt, wie der Request Verification Token vor dem AJAX Request geladen wird.
CSRF Schutz beantwortet aber nicht, ob searchText, Optionswerte oder Zahlen fachlich gültig sind. Er ersetzt auch keine Autorisierung.
Der Token schützt den Request Weg. Server Logic schützt den Request Inhalt.
Wie begrenzt Power Pages Server Logic Request-Größe und Operationen?
Meine Server Logic akzeptiert nur einen JSON Body, der nach dem Parsen ein Objekt ergibt. null, Arrays, primitive Werte und fehlerhaftes JSON werden abgelehnt.
Zusätzlich begrenze ich den serialisierten Body auf 8192 UTF-8 Bytes.
Diese Grenze ist ein Vertrag meiner Suchanwendung. Sie ist kein allgemeines Power Pages Plattformlimit.
Ich messe Bytes statt JavaScript Zeichenlänge, weil Umlaute und andere Unicode Zeichen mehr als ein Byte benötigen können:
const MAX_BROWSER_PAYLOAD_BYTES = 8192;
function getUtf8ByteLength(value) {
let bytes = 0;
for (let index = 0; index < value.length; index += 1) {
const codePoint = value.codePointAt(index);
if (codePoint <= 0x7f) bytes += 1;
else if (codePoint <= 0x7ff) bytes += 2;
else if (codePoint <= 0xffff) bytes += 3;
else {
bytes += 4;
index += 1;
}
}
return bytes;
}
function parseBrowserBody(body) {
let payload;
let serialized;
if (typeof body === 'string') {
serialized = body;
payload = JSON.parse(body);
} else {
if (body === null || typeof body !== 'object' || Array.isArray(body)) {
throw new Error('Search payload must be a JSON object.');
}
serialized = JSON.stringify(body);
payload = body;
}
if (getUtf8ByteLength(serialized) > MAX_BROWSER_PAYLOAD_BYTES) {
throw new Error('Search payload must not exceed 8192 bytes.');
}
if (payload === null || typeof payload !== 'object' || Array.isArray(payload)) {
throw new Error('Search payload must be a JSON object.');
}
return payload;
}Die Größenbegrenzung löst kein allgemeines Denial of Service Problem. Sie verhindert aber, dass dieser konkrete Endpunkt beliebig große Filterverträge verarbeitet.
Nach der Body Prüfung folgt eine feste Operations Allowlist:
const OPERATIONS = {
SEARCH: 'search',
SUGGEST: 'suggest',
DETAILS: 'getPortalCatalogDetails',
};
function readBrowserPayload() {
const payload = parseBrowserBody(Server.Context.Body);
if (!Object.values(OPERATIONS).includes(payload.operation)) {
throw new Error('Server Logic operation must be "search", "suggest", or "getPortalCatalogDetails".');
}
return payload;
}
function post() {
const payload = readBrowserPayload();
if (payload.operation === OPERATIONS.SEARCH) {
return postSearch(payload);
}
if (payload.operation === OPERATIONS.SUGGEST) {
return postSuggest(payload);
}
return postPortalCatalogDetails(payload);
}Die Operation ist verbindlich. Fehlende und unbekannte Werte beenden den Request vor dem Custom API Aufruf.
Danach gelten getrennte Verträge. Search ignoriert unbekannte optionale Filter. Suggest verlangt einen String für searchText. Der Detail-Batch lehnt unbekannte Felder und Nicht-String-Mitglieder vollständig ab.
Der Beitrag zu Power Pages Favoriten mit Batch-GUIDs und Server Logic dokumentiert diese strengere Prüfung sowie invalidIds und notFoundIds.
Wie leitet Power Pages Server Logic Autorisierung ab?
Der Browser darf keinen Wert wie isauthorized bestimmen.
Server Logic leitet diesen Zustand aus dem aktuellen Power Pages Nutzer ab:
function buildApiPayload(browserPayload) {
return {
lcid: browserPayload.lcid,
isauthorized: Server.User !== null,
};
}Selbst wenn ein manipulierter Request isauthorized: true enthält, wird dieser Wert ignoriert. Der Custom API Parameter entsteht neu aus dem serverseitigen Sitzungskontext.
Dieser boolesche Wert ist Teil des fachlichen Custom API Vertrags. Er ersetzt nicht die Plattformberechtigungen.
Die Microsoft Übersicht zur Absicherung von Server Logic beschreibt Webrollen, Tabellenberechtigungen und die Power Pages Sitzung als Grundlage für Zugriff und Ausführung.
Ich prüfe deshalb zwei getrennte Ebenen:
- Darf der aktuelle Portalnutzer diese Server Logic über seine Webrolle ausführen?
- Welche serverseitig abgeleiteten Werte erhält die Custom API für ihre eigene Geschäftslogik?
Diese Ebenen ergänzen sich. Sie dürfen nicht zu einem einzigen Browserfeld zusammenfallen.
Wie validiert Power Pages Server Logic Suchfilter?
Nach der Request Prüfung normalisiert Server Logic jeden unterstützten Filter einzeln.
Zeichenketten erhalten Typ und Maximallänge. Optionswerte müssen in einer festen Allowlist stehen. Doppelte Array Werte werden entfernt. Zahlen müssen endlich sein und werden auf bekannte Domänen begrenzt.
Ein ungültiger einzelner Filter verwirft nicht automatisch die vollständige Suche. Der fehlerhafte Wert wird entfernt. Andere gültige Filter bleiben erhalten.
Bei der vollständigen Suchoperation wird der Request nur abgelehnt, wenn sein Body unbrauchbar ist oder die Operation nicht unterstützt wird. Ungültige optionale Suchfilter werden entfernt.
Die Suggest Operation besitzt zusätzlich ein erforderliches searchText Feld. Ein falscher Typ oder mehr als 100 Zeichen beenden diesen Request mit einem Fehler.
Wie diese Server-Prüfung mit Debounce, Request-Sequenz und den sichtbaren Zuständen im React Eingabefeld zusammenspielt, zeigt der Beitrag über Power Pages Auto-Suggest mit React.
Dieses Verhalten ist wichtig für stabile Suchseiten. Ein beschädigter optionaler URL Parameter darf gültige Filter nicht verstecken. Ein manipulierter Operationswert darf dagegen niemals stillschweigend zu einer Standardsuche werden.
Die konkreten Geschäftsregeln bleiben feldbezogen:
function sanitizeKnownArray(value, isSupported) {
if (!Array.isArray(value)) {
return undefined;
}
const sanitized = [];
for (const item of value) {
if (isSupported(item) && !sanitized.includes(item)) {
sanitized.push(item);
}
}
return sanitized.length > 0 ? sanitized : undefined;
}
function sanitizeOptionSetArray(value, allowedValues) {
return sanitizeKnownArray(value, (item) => Number.isInteger(item) && allowedValues.includes(item));
}Der Browser liefert Kandidaten. Die serverseitige Allowlist entscheidet, welche Werte Teil des Backend Requests werden.
Eingabe | Behandlung | Begründung |
|---|---|---|
Ungültiger JSON Body | Request ablehnen | Kein nutzbarer Eingabevertrag vorhanden |
Unbekannte Operation | Request ablehnen | Keine stillschweigende Standardoperation |
Ungültiger optionaler Filter | Wert entfernen | Andere gültige Filter bleiben verwendbar |
Manipulierte Autorisierung | Browserwert ignorieren | Nutzerstatus entsteht aus der Portalsitzung |
Unbekanntes optionales Feld | Nicht weiterreichen | Nur dokumentierte Felder beeinflussen Backend Request |
Die Support-Matrix der Power Pages Suchfilter zeigt für jede Filtergruppe, welche Prüfung im Browser, in Server Logic und in der Dataverse Abfrage tatsächlich umgesetzt ist.
Wie erzeugt Power Pages Server Logic sichere OData-Filter?
Die React Anwendung sendet keine fertigen OData Filter.
Server Logic baut objectfilter, areafilter und levelfilter ausschließlich aus akzeptierten Feldern auf. Feldnamen, Operatoren und Verknüpfungen stehen im serverseitigen Code.
Nur die geprüften Werte kommen aus dem Browservertrag.
Zeichenketten werden für OData String Literale maskiert. Ein Apostroph wird verdoppelt:
function quoteODataString(value) {
return "'" + value.replace(/'/g, "''") + "'";
}
function buildSearchTextClause(searchText) {
const value = quoteODataString(searchText.toLowerCase());
return 'contains(tolower(name),' + value + ')';
}Dieses Escaping macht nicht jeden beliebigen OData Ausdruck sicher.
Es funktioniert, weil der Browser nur einen Wert liefert. Der Feldname name, der Operator contains und die Klammerstruktur bleiben fest im Servercode.
Ich akzeptiere deshalb keine dynamischen Feldnamen, Operatoren oder vollständigen Filterklauseln aus dem Request.
Ein weiterer Grundsatz ist ebenso wichtig. Ein Filter wird nicht an die Custom API gemappt, solange sein Backend Vertrag nicht bestätigt ist. Eine sichtbare Auswahl im Frontend reicht nicht als Beleg für einen sicheren Datenvertrag.
Der Deep Dive Power Pages OData-Filter aus festen Bausteinen erzeugen zeigt zusätzlich die Gruppierung mit and und or sowie die Zuordnung zu objectfilter, areafilter und levelfilter.
Wie protokolliert Power Pages Server Logic ohne Suchdaten?
Für den Betrieb brauche ich nachvollziehbare Signale.
Ich protokolliere deshalb die Operation, den Locale Wert und Ergebniszahlen. Suchtext, erzeugte OData Filter und ausgewählte IDs bleiben aus dem Log.
Vollständige Custom API Inhalte oder aufgelöste Detail-DTOs gehören nicht in Produktionslogs. Temporäre Debug-Ausgaben müssen vor der Bereitstellung entfernt werden. Für Details reichen Entitätstyp, Sprache, Trefferstatus und aggregierte Anzahlen.
function logOperationMetrics(operation, lcid, resultCount, selectionCount) {
Server.Logger.Log(
'Server logic operation metrics: ' +
JSON.stringify({
operation,
lcid,
resultCount,
selectionCount,
})
);
}Damit kann ich erkennen, ob search oder suggest aufgerufen wurde und wie groß die akzeptierte Antwort war. Ich schreibe keine Nutzereingabe in eine zusätzliche Protokollfläche.
Diese Reduktion ist absichtlich. Mehr Logdaten bedeuten nicht automatisch bessere Diagnose. Sie können Datenschutz, Zugriffskontrolle und Aufbewahrung komplizierter machen.
Warum müssen Fehler in Power Pages Server Logic sichtbar bleiben?
Eine leere Trefferliste ist ein gültiges Suchergebnis.
Ein nicht parsebarer Custom API Body ist kein leeres Suchergebnis.
Meine Server Logic wirft deshalb Fehler weiter, wenn die Custom API keinen erfolgreichen Status, keinen erwarteten String Body oder keine gültige Ergebnisstruktur liefert. Der React Transport lehnt das Promise ebenfalls ab, wenn Server Logic einen Fehler meldet.
Die Oberfläche kann dadurch zwei Situationen unterscheiden:
- Die Suche war erfolgreich und besitzt keine Treffer.
- Die Suche konnte technisch nicht abgeschlossen werden.
Ein erfolgreicher Ersatzwert wie { results: [] } würde einen Vertragsfehler verbergen. Nutzer sehen dann scheinbar keine Daten, obwohl die Integration beschädigt ist.
Diese Regel gilt auch im Browser. Der Transport liest eine konkrete Fehlermeldung aus der HTTP Antwort und verwendet nur dann eine allgemeine Meldung, wenn der Server keine verwertbare Nachricht liefert.
Den vollständigen Weg vom Transport Interface über die verschachtelten Antwort-Envelopes bis zum geprüften Consumer-Vertrag dokumentiere ich im Beitrag über typisierte React und Dataverse Schnittstellen.
Welche Sicherheitsgrenzen ergänzt Power Pages Server Logic?
Server Logic ist die verbindliche fachliche Grenze dieser Suche. Sie ist nicht die einzige Sicherheitsmaßnahme des Portals.
Webrollen steuern, wer den Endpunkt aufrufen darf. Tabellenberechtigungen steuern Dataverse Zugriffe. Der CSRF Token schützt clientseitige Requests. Parser prüfen auch Antworten. Eine Content Security Policy begrenzt, welche Skripte und Ziele der Browser verwenden darf.
Gerade der Browser bleibt ein eigener Risikobereich. Mein Beitrag über Supply Chain Angriffe in Power Pages zeigt, warum ein fremdes Skript trotz sauberer Server Logic weiterhin Portalzustand und Nutzerdaten im Browser gefährden kann.
Für die allgemeine Einordnung von React als isoliertes Widget beschreibt die Power Pages React Frontend Architektur, wann Pro-Code sinnvoll ist und welche Plattformgrenzen erhalten bleiben müssen.
Die Sicherheitsarchitektur besteht deshalb aus mehreren kontrollierten Grenzen. Server Logic übernimmt die Grenze für Request Inhalt, serverseitige Geschäftsregeln und den Übergang zur Dataverse Custom API.
Sicherheitsmaßnahme | Schützt | Ersetzt nicht |
|---|---|---|
CSRF Token | Request Weg aus gültigem Seitenkontext | Feldvalidierung und Autorisierung |
Webrollen | Zugriff auf Server Logic | Prüfung des Request Inhalts |
Tabellenberechtigungen | Zugriff auf Dataverse Datensätze | Fachlichen Custom API Vertrag |
Server Logic | Request Inhalt und Backend Parameter | Plattformberechtigungen und Browser Schutz |
Content Security Policy | Erlaubte Skripte und Browserziele | Serverseitige Eingabeprüfung |
Power Pages Server Logic Sicherheitsgrenze: Erfahrungen aus dem Projekt
Ich habe dieses Muster für eine komplexe Enterprise-Suche in Power Pages umgesetzt.
Die React Anwendung unterstützt mehrere Suchmodi, umfangreiche Filter, Auto-Suggest und entkoppelte Ergebnisverbraucher. Server Logic akzeptiert davon nur den definierten Request-Vertrag und baut die erlaubten Custom API Parameter selbst.
Die öffentliche ECE Fallstudie zur Power Pages Enterprise-Suche zeigt den Projektkontext und die vollständige Architektur. Der technische Beitrag bleibt bewusst generalisiert.
Ich verkaufe damit keine fertige Suchsoftware. Ich dokumentiere, wie ich geschäftskritische Power Pages Workflows so aufbaue, dass Browser, Server Logic und Dataverse klar getrennte Verantwortlichkeiten besitzen.
Du planst eine React Anwendung in Power Pages, die sensible Geschäftsregeln oder eine Custom API nutzt? Im Power Pages Pro-Code Bereich zeige ich, wie ich Sicherheitsgrenzen, Verträge und Umsetzungsrisiken vor der Entwicklung kläre.
