Schützen von Geheimnissen mithilfe von Plattformfunktionen
Lernziele
Nachdem Sie diese Lektion abgeschlossen haben, sind Sie in der Lage, die folgenden Aufgaben auszuführen:
- Auflisten der Optionen und empfohlenen Vorgehensweisen für die Speicherung von Geheimnissen in verwalteten Paketen
- Erstellen von Anmeldeinformationen mit Namen, um Callout-Endpunkte und die zugehörigen Authentifizierungsparameter sicher zu definieren
- Beschreiben, wie geschützte benutzerdefinierte Einstellungen und API-Felder für Metadaten zum Speichern von Geheimnissen genutzt werden können
Speichern von Anwendungsgeheimnissen in Salesforce
In der vorherigen Lektion wurde behandelt, wie Geheimnisse erkannt werden und wer Zugang zu ihnen haben sollte. Als Nächstes sehen wir uns an, wie sie geschützt werden.
Die Salesforce Platform verfügt über eine Reihe von Funktionen, die zum Speichern und Schützen von Geheimnissen eingesetzt werden können. Dazu gehören:
- Anmeldeinformationen mit Namen
- Benutzerdefinierte Einstellungen (geschützt, nicht geschützt, nicht verwaltet und verwaltet)
- Benutzerdefinierte Metadatentypen
In dieser Lektion lernen Sie jede dieser Optionen zur Speicherung von Geheimnissen kennen, damit Sie sicherstellen können, dass der Zugriff auf sensible Informationen entsprechend eingeschränkt ist.
Anmeldeinformationen mit Namen
Anmeldeinformationen mit Namen sind ein Mechanismus für die sichere Verwaltung von Authentifizierungswerten für externe Provider und Services. Sie bieten Prozesse für die Implementierung standardmäßiger Authentifizierung in Form sicherer, verwaltbarer Entitäten. Salesforce verwaltet die gesamte Authentifizierung für Apex-Callouts, die Anmeldeinformationen mit Namen als Endpunkt angeben. Sie müssen also Ihrem Apex-Code keine weitere Authentifizierungslogik hinzufügen. Anmeldeinformationen mit Namen können definiert werden, um eine sichere und praktische Methode zum Einrichten dieser Art von Callouts zu bieten. Nach der Erstellung können Sie hartcodierte URL-Verweise in Ihrem Code durch Verweise auf die Anmeldeinformationen mit Namen ersetzen, was den Code sauberer, einfacher und sicherer macht.
Anmeldeinformationen mit Namen sind nützlich beim Definierten von Callout-Endpunkten, auf die in Ihrem verwalteten Paket verwiesen wird. Ohne Anmeldeinformationen mit Namen muss der Entwickler die folgenden Zusatzaufgaben durchführen, um einen authentifizierten Callout einzurichten.
- Verweisen auf den URL als Callout-Endpunkt
- Registrieren des URL in Ihren Einstellungen für Remote-Standort
- Hinzufügen von benutzerdefiniertem Code, um zugehörige Authentifizierungsaufgaben durchzuführen
Nehmen wir zum Beispiel an, Sie haben eine Anwendung, die sich regelmäßig mit einem externen Service verbindet, um Daten abzurufen. Dieser externe Service erfordert jedoch, dass jede Anforderung einen API-Schlüssel zur Authentifizierung enthält. Häufig erfüllen Entwickler diese Bedingung dadurch, dass sie diesen Schlüssel im Quellcode hartcodieren, damit er in jeder Anforderung verwendet werden kann. Betrachten Sie dieses Codebeispiel:
String key = ’supersecurepassword’; HttpRequest req = new HttpRequest(); req.setEndpoint(’https://www.example.com/test?APIKEY=’+key); req.setMethod(’GET’); Http http = new Http(); HTTPResponse res = http.send(req); return res.getBody();
Das Hardcodieren von Geheimnissen ist zwar eine naheliegende Lösung, es gibt bei diesem Ansatz jedoch drei Hauptprobleme.
- Jeder, der den Quellcode einsehen kann, sieht auch die eingebetteten Geheimnisse.
- Wenn ein Geheimnis aktualisiert wird, müssen Sie alle Vorkommen des Geheimnisses im gesamten Quellcode ändern.
- Das Portieren dieses Geheimnisses zwischen Anwendungen kann zu vielen weiteren Komplikationen führen.
Hier können Anmeldeinformationen mit Namen die Rettung sein! Anstatt den Wert hart in Ihren Code zu codieren, können Sie Anmeldeinformationen mit Namen nutzen, um Geheimnisse zu speichern. Dies ermöglicht Ihnen, für den Zugriff auf den Geheimniswert auf die Anmeldeinformation mit Namen zu verweisen, als ob es sich um eine andere Variable in Ihrem Code handelt.
Vorteile von Anmeldeinformationen mit Namen
Anmeldeinformationen mit Namen stellen nicht nur eine Möglichkeit dar, den Zugriff auf Ihre Anwendungsgeheimnisse einzuschränken, sondern machen zudem die Wartung dieser Geheimnisse zum Kinderspiel. Wenn Sie Anmeldeinformationen mit Namen konfiguriert haben, können Sie diese bei Bedarf leicht ändern, indem Sie sie in Ihren Einstellungen ändern. Alle Vorkommen in Ihrem Code, die auf das Geheimnis verweisen, enthalten immer aktualisierte Werte, da sie direkt auf die Anmeldeinformationen mit Namen verweisen.
Wo bieten sich Anmeldeinformationen mit Namen an?
Auch wenn es ziemlich einfach ist, Anmeldeinformationen mit Namen einzurichten, sind sie nicht unbedingt für jeden Anwendungsfall eine geeignete Lösung. Sie eignen sich am besten für standardmäßige Authentifizierungsprotokolle wie Benutzername und Kennwort, OAuth 2.0, AWS Signature Version 4 und signierte JWTs.
Sie haben den Zweck, Administratoren und Entwicklern in Ihrer Organisation die Arbeit einfacher und sicherer zu machen. Allerdings sind sie nicht immer die beste Wahl. Da Benutzer mit der Berechtigung "Alle Daten modifizieren" oder "Apex erstellen" die Anmeldeinformationen mit Namen ändern oder einen Callout dafür vornehmen dürfen, können sie auch auf die durch die Anmeldeinformationen mit Namen geschützten Daten zugreifen. Oder sie können vielleicht sogar die Anmeldeinformationen selbst auslesen. Falls Sie Schutz vor diesen Anwendungsfällen benötigen, z. B. im Fall eines unabhängigen Softwareherstellers, der ein Paket erstellt, das mit Ihren eigenen Cloud-Services privat kommunizieren muss, sollten Sie andere Optionen wie "Verwaltete geschützte benutzerdefinierte Einstellungen" oder "Verwaltete geschützte benutzerdefinierte Metadatentypen" in Betracht ziehen. Mehr dazu erfahren Sie im nächsten Abschnitt.
Neue Funktionalität für Anmeldeinformationen mit Namen und externen Anmeldeinformationen
Die neue Funktionalität für Anmeldeinformationen mit Namen und externen Anmeldeinformationen in Salesforce ist darauf ausgelegt, die Sicherheit zu verbessern und externe Integrationen zu optimieren. Externe Anmeldeinformationen zeigen die Details dazu, wie Salesforce sich mit einem Authentifizierungsprotokoll bei einem externen System authentifiziert und dabei Berechtigungssätze, Profile und optionale benutzerdefinierte Kopfzeilen verknüpft. Benutzer mit den erforderlichen Berechtigungen können externe Anmeldeinformationen anzeigen, erstellen, bearbeiten und löschen.
Anmeldeinformationen mit Namen fungieren als logische Verbindungen zu externen Systemen, wodurch es nicht mehr notwendig ist, physische URLs in Apex-Code einzubetten und Authentifizierungstoken in unverschlüsselten Datenspeichern zu verwalten. Sie geben den URL eines Callout-Endpunkts und die zugehörigen erforderlichen Authentifizierungsparameter in einer einzelnen Definition an. Anmeldeinformationen mit Namen unterstützen unterschiedliche Typen wie etwa "Secured Endpoint (Gesicherter Endpunkt), "Private Endpoint (Privater Endpunkt)" und "Legacy (Veraltet)".
Für die Interaktion zwischen Anmeldeinformationen mit Namen und externen Anmeldeinformationen müssen zuerst ein Satz mit externen Anmeldeinformationen erstellt und dabei das Authentifizierungsprotokoll und der Berechtigungssatz oder das Profil festgelegt werden. Danach wird ein Satz mit Anmeldeinformationen mit Namen erstellt, die als Callout-Endpunkt für external Services dienen. Die Authentifizierungsdetails für die externen Anmeldeinformationen werden mit den Anmeldeinformationen mit Namen verknüpft, was sichere und authentifizierte Callouts ermöglicht.
Berechtigungssätze spielen eine wichtige Rolle bei der Steuerung des Zugriffs auf externe Services. Externe Anmeldeinformationen authentifizieren Benutzer, während Berechtigungssätze Benutzer autorisieren. Prinzipale in externen Anmeldeinformationen werden Benutzerberechtigungen zugeordnet. Dies stellt vor dem Zugriff auf Remote-Systeme sicher, dass Benutzer über die nötige Autorisierung verfügen. Externe Benutzeranmeldeinformationen speichern verschlüsselte Token und bieten damit eine sichere Methode, die benutzerspezifische Authentifizierung zu verwalten.
Benutzerdefinierte Kopfzeilen können sowohl zu Anmeldeinformationen mit Namen als auch externen Anmeldeinformationen hinzugefügt werden und ermöglichen, dass Salesforce-Aufrufe an Remote-Systeme benutzerdefinierte Parameter enthalten, die für die Beantwortung von Anforderungen notwendig sind. Diese Anpassung erhöht die Flexibilität und deckt verschiedene Anwendungsfälle und Sicherheitsanforderungen ab.
Die Salesforce Platform empfiehlt, Anmeldeinformationen mit Namen als auch externe Anmeldeinformationen über die Salesforce-Benutzeroberfläche zu erstellen und zu bearbeiten. Sie können dazu aber auch die Metadaten-, Tooling- oder Connect REST-APIs verwenden. Insgesamt bietet die Funktionalität für Anmeldeinformationen mit Namen und externen Anmeldeinformationen einen zuverlässigen, anpassbaren Ansatz für die Verwaltung sicherer und authentifizierter externer Integrationen.
Sichere verteilte Geheimnisse
Anmeldeinformationen mit Namen sind ideal für Callouts an externe Services in einer Organisation, in der Administratoren auf die zugehörigen Authentifizierungsgeheimnisse zugreifen dürfen. Aber was tun Sie, wenn Sie verhindern müssen, dass Administratoren die Daten einsehen, oder wenn Sie Geheimnisse auf mehrere Salesforce-Organisationen verteilen möchten?
In diesen Fällen sollten Sie Code als verwaltetes Paket verteilen. Sie können ganz einfach eine kostenlose Developer Edition-Organisation als Paketerstellungsorganisation für Ihren Code einrichten. Wenn Sie AppExchange-Partner sind, können Sie Developer Edition-Organisationen über Ihr Umfeldzentrum erstellen. Sie können auch die Seite zum Registrieren für eine Developer Edition aufrufen. Innerhalb Ihrer Paketerstellungsorganisation können Sie Apex-Klassen, Apex-Auslöser, Salesforce-Objekte und andere gängige Formen von Metadaten in einem verwalteten Paket bündeln, das problemlos an jede andere Salesforce-Instanz oder -Organisation verteilt werden kann. Sie können sich ein verwaltetes Paket als eine komplexere Version einer ZIP-Datei vorstellen.
Unter Sicherheitsaspekten bietet die Verwendung verwalteter Pakete (im Gegensatz zu nicht verwalteten Paketen oder losem Code) viele bedeutende Vorteile.
- Verwaltete Pakete verfügen über die erforderlichen Mechanismen, um automatische Updates, Patches und Fehlerbehebungen per Push-Verfahren zu verteilen, wenn Sicherheitslücken erkannt werden.
- Ihr Quellcode ist verborgen (außer bei explizit offen gelegten globalen Apex-Klassen). Das heißt, dass grundlegende Geschäfts- oder Programmlogik nicht so verändert werden kann, dass sie unbeabsichtigt nicht mehr funktioniert oder bösartig modifiziert und neu verteilt wird. Verborgener Code verhindert auch, dass im Paket enthaltene Geheimnisse sichtbar sind.
- Da Sie für Ihr verwaltetes Paket einen eindeutigen Namespace definieren müssen, werden Probleme durch Namespace-Konflikte verhindert. Außerdem wird Ihr Paket vom lokalen Namespace getrennt, wodurch die in Ihrem Paket enthaltenen Geheimnisse weiter geschützt sind. Standardmäßig kann mit Code, der außerhalb eines verwalteten Pakets ausgeführt wird, nicht auf Paketgeheimnisse zugegriffen werden.
Verwalteten geschützter benutzerdefinierter Einstellungen und benutzerdefinierter Metadatentypen
Während das einfache Packen Ihres Codes in einem verwalteten Paket viele Sicherheitsvorteile bietet, stehen Ihnen bei Verwendung eines verwalteten Pakets auch zwei weitere Funktionen für die Speicherung und Verteilung von Informationen zur Verfügung: geschützte benutzerdefinierte Einstellungen und geschützte benutzerdefinierte Metadaten.
Benutzerdefinierte Einstellungen können für die Speicherung nahezu aller Arten von Daten erstellt werden und sind äußerst flexibel in Bezug auf ihre Einsatzmöglichkeiten und Inhalte. Zusammenfassend lässt sich sagen, dass Sie mit benutzerdefinierten Einstellungen benutzerdefinierte Datensets erstellen können, die dem Anwendungs-Cache offengelegt werden, sodass Sie wiederholte Datenbankabfragen vermeiden und die Effizienz Ihrer Anwendung steigern können. Eine benutzerdefinierte Einstellung kann z. B. dazu dienen, eine Reihe von Daten festzulegen, mit denen die Benutzererfahrung mit einer Anwendung personalisiert wird. Sie könnten auch eine benutzerdefinierte Einstellung erstellen, um eine Liste von Produktnamen zu speichern, auf die auf zahlreichen Seiten verwiesen wird, um schnellen und einfachen Zugriff zu ermöglichen. Im Hinblick auf Anwendungssicherheit können benutzerdefinierte Einstellungen zum Einsatz kommen, um sensible Informationen oder Geheimnisse zu speichern.
Für benutzerdefinierte Einstellungen können unterschiedliche Sichtbarkeitsstufen festgelegt werden. Eine in einem verwalteten Paket enthaltene geschützte benutzerdefinierte Einstellung ist für abonnierende Organisationen weder über Apex noch über die API sichtbar, wodurch es sich gut eignet, bestimmte Arten von Geheimnissen zu speichern. Benutzerdefinierte Einstellungen, die auf öffentliche Sichtbarkeit festgelegt oder in einem nicht verwalteten Paket enthalten sind, lassen sich über Enterprise Web Service Description Language (WSDL) einsehen. Daher ist es wichtig, dass geschützte benutzerdefinierte Einstellungen in einem verwalteten Paket gekapselt werden, wenn sensible Informationen darin abgelegt werden.
Benutzerdefinierte Metadatenfelder können ähnlich wie benutzerdefinierte Einstellungen für die Speicherung von Geheimnissen verwendet werden. Für einen angemessenen Schutz legen Sie die Sichtbarkeit der Felder auf "Protected (Geschützt)" fest und legen sie in einem verwalteten Paket ab. Geschützte benutzerdefinierte Felder der Metadaten-API eignen sich beispielsweise hervorragend für die Speicherung von API-Schlüsseln oder anderen geheimen Schlüsseln.
Hinsichtlich Sichtbarkeitseinstellungen gibt es sowohl bei benutzerdefinierten Einstellungen als auch bei Metadatenfeldern mehrere Optionen.
- Öffentlich (lokal)
- Geschützt (lokal)
- Öffentlich (verwaltet)
- Geschützt (verwaltet)
Die ersten drei Optionen eignen sich für die Speicherung von Daten im Allgemeinen, doch bei Wahl dieser Einstellung kann jeder in der Organisation die Datenwerte einsehen. Wählen Sie diese Optionen nur, wenn Sie öffentlich zugängliche Daten speichern. Für sensible Daten, wie z. B. Anwendungsgeheimnisse, wählen Sie die Konfigurationsoption "Geschützt (Verwaltet)".
Durch die Möglichkeit, die Sichtbarkeit zu deaktivieren, den einfachen Zugriff und die Zwischenspeicherfunktionalität sind benutzerdefinierte Einstellungen und Metadatenfelder geeignete und attraktive Methoden für die Speicherung von Geheimnissen.
Erstellen verwalteter, geschützter benutzerdefinierter Einstellungen
Sie können eine verwaltete, geschützte benutzerdefinierte Einstellung namens "District Secrets" erstellen, um darin Geheimnisse sicher zu speichern. Zum Erstellen eine geschützten benutzerdefinierten Einstellung gehen Sie in das Setup wechseln zu "Schnellsuche Benutzerdefinierte Einstellungen" und klicken auf "Neu". Definieren Sie Bezeichnung, Objektname, Einstellungstyp und Sichtbarkeit (legen Sie hier "Geschützt" fest). Nachdem Sie auf "Speichern" geklickt haben, können Sie benutzerdefinierte Felder zum Speichern der Geheimnisse hinzufügen.
Endlich können Sie Ihre Geheimnisse in Ihre geschützten benutzerdefinierten Felder eingeben. Da nur Einstellungsdefinitionen in das Paket einbezogen werden, benötigen Sie Apex oder ein API-Skript, um die Geheimnisse einzutragen, wenn das Paket in der Ziel- oder Abonnentenorganisation installiert wurde.
Verwenden verwalteter geschützter benutzerdefinierter Einstellungen
Sie können auf benutzerdefinierte Einstellungen auf dieselbe Weise wie auf benutzerdefinierte Objekte verweisen. Für den Zugriff auf benutzerdefinierte Einstellungen können Sie Formelfelder, Apex-Methoden für benutzerdefinierte Einstellungen, SOAP-API, Validierungsregeln, Flow usw. verwenden. Verweise auf die geschützte benutzerdefinierte Einstellung können innerhalb desselben verwalteten Pakets, d. h. im gleichen Namespace, vorgenommen werden. Es folgen gängige Apex-Methoden zum Verweisen auf benutzerdefinierte Einstellungen:
-
getInstance()
-
getInstance(userId)
-
getInstance(profileId)
-
getOrgDefaults()
-
getValues(userId)
-
getValues(profileId)
Im folgenden Beispiel wird getInstance()
für den Zugriff auf Geheimnisse verwendet, die als benutzerdefinierte Einstellungskomponente gespeichert sind.
CustomSettingName__c cmcs=CustomSettingName__c.getInstance();
Benutzerdefinierte Metadatentypen
Geschützte benutzerdefinierte Metadatentypen können ebenfalls zum Speichern von Geheimnissen definiert werden, ähnlich wie benutzerdefinierte Einstellungen. Benutzerdefinierte Metadatentypen sollten für die Einbindung in ein verwaltetes Paket definiert werden, damit sie wirksam verborgen und geschützt sind. Der Hauptunterschied besteht darin, dass die in benutzerdefinierten Metadatentypen enthaltenen Daten Metadaten in Ihrer Anwendung darstellen.
Dies ist oft von Vorteil. Stellen Sie sich vor, Sie sind ein Entwickler, der in Ihrer Developer Edition-Paketerstellungsorganisation eine neue Anwendung erstellt. Diese Anwendung verfügt über viele coole Funktionen, einschließlich einer externen API-Integration mit example.com. Für Callouts an example.com müssen Sie irgendwo einen API-Schlüssel speichern. Eine Möglichkeit besteht darin, den geheimen API-Schlüssel in einem benutzerdefinierten Feld zu speichern. Das funktioniert zwar in Ihrer eigenen Developer Edition-Organisation, hat aber auch Nachteile. Also, was ist an diesem Ansatz falsch?
Abgesehen davon, dass es sich um eine unsichere Lösung handelt, gibt es ein Problem mit dem Speichern des geheimen API-Schlüssels in einem benutzerdefinierten Feld, sobald es zu einer erneuten Bereitstellung kommt. Wenn Sie versuchen, all Ihren Code und Ihre Anpassungen in Ihre Produktionsorganisation zu verschieben, wird der Wert Ihres geheimen Schlüssels nicht gleichzeitig übertragen. Ihre Daten werden nicht mit Ihrem Änderungsset in die Produktion verschoben. Sie müssen den Schlüsselwert manuell in das Feld einfügen oder ein Skript schreiben, um das Feld ausfüllen zu lassen. Bei einem benutzerdefinierten Metadatentyp hingegen wird der geheime API-Schlüssel wie jede andere Anpassung behandelt und in die Produktion überführt. In diesem Szenario müssen Sie ihn nicht selbst wieder einfügen.
Wie bereits erwähnt, müssen Sie, um Daten eine benutzerdefinierten Einstellung zu laden, ein Skript zur Ausführung nach der Installation schreiben. Bei geschützten benutzerdefinierten Metadatentypen müssen Sie jedoch keine Skripts schreiben. Die in einem benutzerdefinierten Metadatentyp enthaltenen Daten stehen als separate Metadaten zur Verfügung, die Sie dem Paket hinzufügen können. Das hört sich doch gut an, oder?
Eine der besten Eigenschaften benutzerdefinierter Metadatentypen ist, dass Sie sie wie beliebige andere benutzerdefinierte Objekte mit SOQL abfragen können. Der einzige Unterschied besteht darin, dass Metadatentypen das Suffix __mdt
anstelle von __c
haben. Wenn Sie einen benutzerdefinierten Metadatentyp auswählen müssen, schreiben Sie eine Abfrage wie diese:
SELECT Teacher__c, Coach__c, Counselor__c , Administrator__c FROM District_Profiles__mdt
Diese Codezeile ruft alle Werte von District_Profiles__mdt
ab. Das ist ziemlich einfach!
Benutzerdefinierte Einstellungen und benutzerdefinierte Metadatentypen im Vergleich
Sie können zwar entweder benutzerdefinierte Einstellungen oder benutzerdefinierte Metadatentypen zum Schutz von Geheimnissen einsetzen, doch es gibt einige erwähnenswerte Unterschiede zwischen den beiden. Schauen wir uns an, wann welche genutzt werden sollten.
Verwenden Sie in folgenden Fällen geschützte benutzerdefinierte Einstellungen:
- Das Geheimnis muss häufig aktualisiert werden und sofort verfügbar sein. Da Metadatentypen in eine Warteschlange gestellt und bereitgestellt werden müssen, sind aktualisierte Geheimnisse in Metadatentypen nicht sofort verfügbar. Daher ist eine benutzerdefinierte Einstellung hier die bessere Wahl.
- Sie möchten festlegen, welche Profile und Benutzer auf welche Geheimnisse zugreifen dürfen. Metadatentypen bieten nicht dieselbe Granularität wie hierarchische Typen benutzerdefinierter Einstellungen, bei denen Sie festlegen können, für welche Profile oder Benutzer die Geheimnisse zur Verfügung stehen sollen. Es ist also besser, in diesem Fall eine benutzerdefinierte Einstellung zu wählen.
Verwenden Sie in folgenden Fällen benutzerdefinierte Metadatentypen:
- Sie möchten ohne zusätzliche Konfigurationsschritte ein allgemeines Geheimnis verteilen.
- Benutzerdefinierte Metadatengeheimnisse können einfach migriert werden, z. B. aus einer Sandbox- oder Entwicklungsumgebung in eine Produktionsumgebung. Bei benutzerdefinierten Einstellungen hingegen müssen Administratoren entweder Skripts für die Ausführung nach der Installation schreiben oder Seiten erstellen und in der neuen Umgebung Geheimnisse manuell eingeben und speichern.
Ressourcen
-
Salesforce Developers Blog: Apex-Entwicklerhandbuch: Anmeldeinformationen mit Namen als Callout-Endpunkte
-
Blog für Salesforce-Entwickler: Wie Sie mit benutzerdefinierten Metadatentypen jahrelange Entwicklungsarbeit bei Anwendungskonfigurationen sparen
-
Salesforce Developers Blog: Apex-Entwicklerhandbuch: Methoden für benutzerdefinierte Einstellungen
-
Salesforce-Hilfe: Definieren benutzerdefinierter Einstellungen