Autorisieren des Zugriffs auf Webanwendungen mit OpenID Connect und Azure Active Directory
Warnung
Dieser Inhalt gilt für den älteren v1.0-Endpunkt von Azure AD. Verwenden Sie Microsoft Identity Platform für neue Projekte.
OpenID Connect ist eine einfache Identitätsebene, die auf dem OAuth 2.0-Protokoll basiert. OAuth 2.0 definiert Mechanismen zum Abrufen und Verwenden von Zugriffstoken für den Zugriff auf geschützte Ressourcen, aber sie definieren keine Standardmethoden, um Identitätsinformationen bereitzustellen. OpenID Connect implementiert die Authentifizierung als Erweiterung für den OAuth 2.0-Autorisierungsprozess. Es stellt Informationen über den Endbenutzer in Form einer id_token
bereit, die die Identität des Benutzers überprüft und grundlegende Profilinformationen über den Benutzer bereitstellt.
OpenID Connect ist unsere Empfehlung, wenn Sie eine Webanwendung erstellen, die auf einem Server gehostet und über einen Browser aufgerufen wird.
Registrieren Sie Ihre Anwendung bei Ihrem AD-Mandanten
Registrieren Sie zunächst Ihre Anwendung bei Ihrem Azure Active Directory (Azure AD)-Mandanten. Dadurch erhalten Sie eine Anwendungs-ID für Ihre Anwendung sowie die Möglichkeit, Token zu empfangen.
Melden Sie sich beim Azure-Portal an.
Wählen Sie Ihren Azure AD-Mandanten aus, indem Sie Ihr Konto in der oberen rechten Ecke der Seite auswählen, gefolgt von der Navigation Verzeichnis wechseln und anschließendem Auswählen des entsprechenden Mandanten.
- Überspringen Sie diesen Schritt, wenn Sie nur über einen Azure AD-Mandanten unter Ihrem Konto verfügen oder den entsprechenden Azure AD-Mandanten bereits ausgewählt haben.
Suchen Sie im Azure-Portal nach Azure Active Directory-, und wählen Sie sie aus.
Wählen Sie im linken Menü Azure Active DirectoryApp-Registrierungenaus, und wählen Sie dann Neue Registrierungaus.
Folgen Sie den Anweisungen, und erstellen Sie eine neue Anwendung. Es spielt keine Rolle, ob es sich um eine Webanwendung oder eine öffentliche Clientanwendung (mobile &-Desktopanwendung) für dieses Lernprogramm handelt, aber wenn Sie bestimmte Beispiele für Webanwendungen oder öffentliche Clientanwendungen wünschen, schauen Sie sich unsere Schnellstartsan.
- Name ist der Anwendungsname und beschreibt Ihre Anwendung für Endbenutzer.
- Wählen Sie unter Unterstützte KontotypenKonten in allen Organisationsverzeichnissen und persönliche Microsoft-Konten aus.
- Stellen Sie den Umleitungs-URIbereit. Bei Webanwendungen ist dies die Basis-URL Ihrer App, in der sich Benutzer anmelden können. Beispiel:
http://localhost:12345
. Für öffentlichen Client (mobile & Desktop) verwendet Azure AD diese, um Tokenantworten zurückzugeben. Geben Sie einen bestimmten Wert für Ihre Anwendung ein. Beispiel:http://MyFirstAADApp
.
Nachdem Sie die Registrierung abgeschlossen haben, weist Azure AD Ihrer Anwendung einen eindeutigen Clientbezeichner (die Anwendungs-ID) zu. Sie benötigen diesen Wert in den nächsten Abschnitten, kopieren Sie ihn also von der Anwendungsseite.
Um Ihre Anwendung im Azure-Portal zu finden, wählen Sie App-Registrierungenaus, und wählen Sie dann Alle Anwendungen anzeigenaus.
Authentifizierungsfluss bei OpenID Connect
Der grundlegendste Anmeldefluss enthält die folgenden Schritte– jede davon wird im Folgenden ausführlich beschrieben.
OpenID Connect-Metadatendokument
OpenID Connect beschreibt ein Metadatendokument, das die meisten Informationen enthält, die für die Anmeldung einer App erforderlich sind. Dies umfasst Informationen wie die zu verwendenden URLs und den Speicherort der öffentlichen Signaturschlüssel des Diensts. Das OpenID Connect-Metadatendokument finden Sie unter:
https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration
Die Metadaten sind ein einfaches JSON-Dokument (JavaScript Object Notation). Ein Beispiel finden Sie im folgenden Codeausschnitt. Der Inhalt des Codeausschnitts wird vollständig in der OpenID Connect-Spezifikationbeschrieben. Beachten Sie, dass die Bereitstellung einer Mandanten-ID anstelle von common
anstelle von {tenant} oben zu mandantenspezifischen URIs im zurückgegebenen JSON-Objekt führt.
{
"authorization_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/authorize",
"token_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/token",
"token_endpoint_auth_methods_supported":
[
"client_secret_post",
"private_key_jwt",
"client_secret_basic"
],
"jwks_uri": "https://login.microsoftonline.com/common/discovery/keys"
"userinfo_endpoint":"https://login.microsoftonline.com/{tenant}/openid/userinfo",
...
}
Wenn Ihre App benutzerdefinierte Signaturschlüssel als Ergebnis der Verwendung des Anspruchszuordnungs--Features aufweist, müssen Sie einen appid
Abfrageparameter mit der App-ID anfügen, um eine jwks_uri
abzurufen, die auf die Signaturschlüsselinformationen Ihrer App verweist. Beispiel: https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e
enthält einen jwks_uri
von https://login.microsoftonline.com/{tenant}/discovery/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e
.
Senden der Anmeldeanforderung
Wenn Ihre Webanwendung den Benutzer authentifizieren muss, muss sie den Benutzer an den /authorize
Endpunkt weiterleiten. Diese Anforderung ähnelt dem ersten Abschnitt des OAuth 2.0-Autorisierungscodeflussesmit einigen wichtigen Unterschieden:
- Die Anforderung muss den Bereich
openid
im parameterscope
enthalten. - Der parameter
response_type
mussid_token
enthalten. - Die Anforderung muss den parameter
nonce
enthalten.
Eine Beispielanforderung würde also wie folgt aussehen:
// Line breaks for legibility only
GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%3a12345
&response_mode=form_post
&scope=openid
&state=12345
&nonce=7362CAEA-9CA5-4B43-9BA3-34D7C303EBA7
Parameter | Typ | BESCHREIBUNG |
---|---|---|
Mieter | Erforderlich | Mit dem Wert {tenant} im Pfad der Anforderung kann gesteuert werden, wer sich bei der Anwendung anmelden kann. Die zulässigen Werte sind Mandanten-IDs, z. B. 8eaef023-2b34-4da1-9baa-8bc8c9d6a490 oder contoso.onmicrosoft.com oder common für mandantenunabhängige Token. |
Kunden-ID | Erforderlich | Die Ihrer App zugewiesene Anwendungs-ID, wenn Sie sie bei Azure AD registriert haben. Dies finden Sie im Azure-Portal. Klicken Sie auf Azure Active Directory-, klicken Sie auf App-Registrierungen, wählen Sie die Anwendung aus, und suchen Sie die Anwendungs-ID auf der Anwendungsseite. |
Antworttyp | Erforderlich | Muss id_token für die OpenID Connect-Anmeldung enthalten sein. Sie kann auch andere response_types enthalten, z. B. code oder token . |
Umfang | empfohlen | Die OpenID Connect-Spezifikation erfordert den Bereich openid , der in die Berechtigung "Anmelden" in der Zustimmungs-UI übersetzt wird. Diese und andere OIDC-Bereiche werden auf dem v1.0-Endpunkt ignoriert, sind aber weiterhin eine bewährte Methode für standardskonforme Clients. |
Nonce | Erforderlich | Ein Wert in der von der App erzeugten Anforderung, die im resultierenden id_token -Element als Anspruch enthalten ist. Die App kann diesen Wert dann überprüfen, um die Gefahr von Tokenwiedergabeangriffen zu vermindern. Der Wert ist in der Regel eine zufällige, eindeutige Zeichenfolge oder GUID, die verwendet werden kann, um den Ursprung der Anforderung zu identifizieren. |
Weiterleitungs-URI | empfohlen | Die redirect_uri Ihrer App, an die Authentifizierungsantworten von Ihrer App gesendet und empfangen werden können. Es muss genau mit einem der redirect_uris übereinstimmen, die Sie im Portal registriert haben, es sei denn, es muss URL-codiert sein. Wenn der Benutzer-Agent fehlt, wird er zufällig an eine der für die App registrierten Umleitungs-URIs zurückgesendet. Die maximale Länge beträgt 255 Byte. |
Antwortmodus | wahlfrei | Gibt die Methode an, die zum Senden des resultierenden Autorisierungscode an Ihre App verwendet werden soll. Unterstützte Werte sind form_post für HTTP-Formularbeitrag und fragment für URL-Fragment. Für Webanwendungen wird empfohlen, response_mode=form_post zu verwenden, um die sicherste Übertragung von Token an Ihre Anwendung sicherzustellen. Der Standardwert für jeden Fluss einschließlich eines id_token ist fragment . |
Staat | empfohlen | Ein In der Anforderung enthaltener Wert, der in der Tokenantwort zurückgegeben wird. Dabei kann es sich um eine Zeichenfolge mit beliebigen Inhalten handeln. Ein zufällig generierter eindeutiger Wert wird in der Regel verwendet , um siteübergreifende Anforderungsfälschungsangriffe zu verhindern. Der Status wird auch verwendet, um Informationen über den Status des Benutzers in der App zu codieren, bevor die Authentifizierungsanforderung aufgetreten ist, z. B. Informationen zu der Seite oder Ansicht, die der Benutzer besucht hat. |
prompt | wahlfrei | Gibt den Typ der erforderlichen Benutzerinteraktion an. Derzeit sind die einzigen gültigen Werte "login", "none" und "consent".
prompt=login erzwingt, dass der Benutzer seine Anmeldeinformationen für diese Anforderung eingibt und einmaliges Anmelden negiert.
prompt=none ist das Gegenteil - es stellt sicher, dass dem Benutzer keinerlei interaktive Eingabeaufforderung angezeigt wird. Wenn die Anforderung nicht nahtlos über Single-Sign-On abgeschlossen werden kann, gibt der Endpunkt einen Fehler zurück.
prompt=consent löst das OAuth-Zustimmungsdialogfeld aus, nachdem sich der Benutzer angemeldet hat, und fordert den Benutzer auf, der App Berechtigungen zu erteilen. |
Anmeldehinweis | wahlfrei | Kann verwendet werden, um das Feld "Benutzername/E-Mail-Adresse" der Anmeldeseite für den Benutzer vorab auszufüllen, wenn Sie den Benutzernamen vorab kennen. Häufig verwenden Apps diesen Parameter während der erneuten Authentifizierung, nachdem der Benutzername bereits mit dem preferred_username -Claim aus einer vorherigen Anmeldung extrahiert wurde. |
An dieser Stelle wird der Benutzer aufgefordert, seine Anmeldeinformationen einzugeben und die Authentifizierung abzuschließen.
Beispielantwort
Eine Beispielantwort, die an die in der Anmeldeanforderung angegebene redirect_uri
gesendet wurde, nachdem der Benutzer sich authentifiziert hat, könnte wie folgt aussehen:
POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded
id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&state=12345
Parameter | BESCHREIBUNG |
---|---|
id_token | Der von der App angeforderte id_token . Sie können die id_token verwenden, um die Identität des Benutzers zu überprüfen und eine Sitzung mit dem Benutzer zu beginnen. |
Staat | Ein in der Anforderung enthaltener Wert, der ebenfalls in der Tokenantwort zurückgegeben wird. Ein zufällig generierter eindeutiger Wert wird in der Regel verwendet , um siteübergreifende Anforderungsfälschungsangriffe zu verhindern. Der Status wird auch verwendet, um Informationen über den Status des Benutzers in der App zu codieren, bevor die Authentifizierungsanforderung aufgetreten ist, z. B. Informationen zu der Seite oder Ansicht, die der Benutzer besucht hat. |
Fehlerantwort
Fehlerantworten können auch an den redirect_uri
gesendet werden, damit die App diese angemessen behandeln kann:
POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded
error=access_denied&error_description=the+user+canceled+the+authentication
Parameter | BESCHREIBUNG |
---|---|
Fehler | Eine Fehlercodezeichenfolge, die verwendet werden kann, um unterschiedliche Arten auftretender Fehler zu klassifizieren und um auf Fehler zu reagieren. |
Fehlerbeschreibung | Eine spezifische Fehlermeldung, mit der Entwickler die Hauptursache eines Authentifizierungsfehlers identifizieren können. |
Fehlercodes beim Autorisierungsendpunktfehler
Die folgende Tabelle beschreibt die verschiedenen Fehlercodes, die im error
-Parameter der Fehlerantwort zurückgegeben werden können:
Fehlercode | BESCHREIBUNG | Kundenaktion |
---|---|---|
ungültige_Anfrage | Protokollfehler, z.B. ein fehlender erforderlicher Parameter. | Korrigieren Sie die Anforderung, und senden Sie sie erneut. Dies ist ein Entwicklungsfehler und wird in der Regel während des anfänglichen Tests abgefangen. |
nicht autorisierter Client | Die Clientanwendung darf keinen Autorisierungscode anfordern. | Dies tritt in der Regel auf, wenn die Clientanwendung nicht in Azure AD registriert ist oder dem Azure AD-Mandanten des Benutzers nicht hinzugefügt wird. Die Anwendung kann den Benutzer mit Anweisungen zur Installation der Anwendung und zum Hinzufügen der Anwendung zu Azure AD auffordern. |
Zugriff verweigert | Der Ressourcenbesitzer hat die Zustimmung verweigert. | Die Clientanwendung kann den Benutzer benachrichtigen, dass sie nicht fortfahren kann, es sei denn, der Benutzer stimmt zu. |
nicht unterstützter Antworttyp | Der Autorisierungsserver unterstützt den Antworttyp in der Anforderung nicht. | Korrigieren Sie die Anforderung, und senden Sie sie erneut. Dies ist ein Entwicklungsfehler und wird in der Regel während des anfänglichen Tests abgefangen. |
Serverfehler | Der Server hat einen unerwarteten Fehler erkannt. | Wiederholen Sie die Anforderung. Diese Fehler werden durch temporäre Bedingungen verursacht. Die Clientanwendung kann dem Benutzer erklären, dass seine Antwort aufgrund eines temporären Fehlers verzögert wird. |
vorübergehend nicht verfügbar | Der Server ist vorübergehend überlastet und kann die Anforderung nicht verarbeiten. | Wiederholen Sie die Anforderung. Die Clientanwendung kann dem Benutzer erklären, dass seine Antwort aufgrund einer temporären Bedingung verzögert wird. |
ungültige_ressource | Die Zielressource ist ungültig, da sie nicht vorhanden ist, Azure AD sie nicht finden kann oder nicht ordnungsgemäß konfiguriert ist. | Dies gibt an, dass die Ressource, sofern vorhanden, nicht im Mandanten konfiguriert wurde. Die Anwendung kann den Benutzer mit Anweisungen zur Installation der Anwendung und zum Hinzufügen der Anwendung zu Azure AD auffordern. |
id_token validieren
Das Empfangen einer id_token
reicht nicht aus, um den Benutzer zu authentifizieren; Sie müssen die Signatur überprüfen und die Ansprüche in der id_token
gemäß den Anforderungen Ihrer App überprüfen. Der Azure AD-Endpunkt verwendet JSON-Webtoken (JWTs) und Kryptografie für öffentliche Schlüssel, um Token zu signieren und zu überprüfen, ob sie gültig sind.
Sie können die id_token
im Clientcode überprüfen, aber es empfiehlt sich, die id_token
an einen Back-End-Server zu senden und dort die Überprüfung durchzuführen.
Sie können auch zusätzliche Ansprüche je nach Szenario überprüfen. Einige allgemeine Überprüfungen umfassen:
- Sicherstellen, dass sich der Benutzer/die Organisation für die App registriert hat.
- Sicherstellen, dass der Benutzer über die richtigen Autorisierungs-/Berechtigungen verfügt, indem die
wids
oderroles
Ansprüche verwendet werden. - Es muss sichergestellt werden, dass eine bestimmte Authentifizierungsstärke erfolgt ist, wie zum Beispiel durch eine Multi-Faktor-Authentifizierung.
Nachdem Sie die id_token
überprüft haben, können Sie eine Sitzung mit dem Benutzer beginnen und die Ansprüche in der id_token
verwenden, um Informationen über den Benutzer in Ihrer App abzurufen. Diese Informationen können für Anzeige, Aufzeichnungen, Personalisierung usw. verwendet werden. Weitere Informationen zu id_tokens
und Ansprüchen finden Sie unter AAD id_tokens.
Senden einer Abmeldeanforderung
Wenn Sie den Benutzer bei der App abmelden möchten, reicht es nicht aus, die Cookies Ihrer App zu löschen oder die Sitzung anderweitig mit dem Benutzer zu beenden. Sie müssen den Benutzer auch zum end_session_endpoint
umleiten, um sich abzumelden. Wenn Sie dies nicht tun, kann der Benutzer erneut mit Ihrer App authentifizieren, ohne seine Anmeldeinformationen erneut einzugeben, da er über eine gültige Single Sign-On-Sitzung mit dem Azure AD-Endpunkt verfügt.
Sie können den Benutzer einfach auf die im OpenID Connect-Metadatendokument aufgeführte end_session_endpoint
weiterleiten.
GET https://login.microsoftonline.com/common/oauth2/logout?
post_logout_redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
Parameter | Typ | BESCHREIBUNG |
---|---|---|
post_logout_redirect_uri | empfohlen | Die URL, zu der der Benutzer nach erfolgreicher Abmeldung umgeleitet werden soll. Diese URL muss mit einer der Umleitungs-URIs übereinstimmen, die für Ihre Anwendung im App-Registrierungsportal registriert sind. Wenn post_logout_redirect_uri nicht enthalten ist, wird dem Benutzer eine generische Meldung angezeigt. |
Einmaliges Abmelden
Wenn Sie den Benutzer zum end_session_endpoint
umleiten, löscht Azure AD die Sitzung des Benutzers aus dem Browser. Der Benutzer kann jedoch weiterhin bei anderen Anwendungen angemeldet sein, die Azure AD für die Authentifizierung verwenden. Damit diese Anwendungen den Benutzer gleichzeitig abmelden können, sendet Azure AD eine HTTP GET-Anforderung an die registrierte LogoutUrl
aller Anwendungen, bei denen der Benutzer derzeit angemeldet ist. Anwendungen müssen auf diese Anforderung reagieren, indem jede Sitzung gelöscht wird, die den Benutzer identifiziert und eine 200
Antwort zurückgibt. Wenn Sie einmaliges Abmelden in Ihrer Anwendung unterstützen möchten, müssen Sie eine solche LogoutUrl
im Code Ihrer Anwendung implementieren. Sie können die LogoutUrl
über das Azure-Portal festlegen:
- Melden Sie sich beim Azure-Portal an.
- Wählen Sie Ihr Active Directory aus, indem Sie in der oberen rechten Ecke der Seite auf Ihr Konto klicken.
- Wählen Sie im linken Navigationsbereich Azure Active Directoryaus, und wählen Sie dann App-Registrierungen aus, und wählen Sie Ihre Anwendung aus.
- Klicken Sie auf Einstellungen, dann auf Eigenschaften und suchen Sie das Textfeld Abmelde-URL.
Tokenerwerb
Viele Web-Apps müssen nicht nur den Benutzer anmelden, sondern auch im Namen dieses Benutzers mithilfe von OAuth auf einen Webdienst zugreifen. In diesem Szenario wird OpenID Connect für die Benutzerauthentifizierung kombiniert, während gleichzeitig eine authorization_code
abgerufen wird, die verwendet werden kann, um mithilfe des OAuth-Autorisierungscodeflussesaccess_tokens
abzurufen.
Zugriffstoken abrufen
Um Zugriffstoken zu erwerben, müssen Sie die Anmeldeanforderung von oben ändern:
// Line breaks for legibility only
GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e // Your registered Application ID
&response_type=id_token+code
&redirect_uri=http%3A%2F%2Flocalhost%3a12345 // Your registered Redirect Uri, url encoded
&response_mode=form_post // `form_post' or 'fragment'
&scope=openid
&resource=https%3A%2F%2Fservice.contoso.com%2F // The identifier of the protected resource (web API) that your application needs access to
&state=12345 // Any value, provided by your app
&nonce=678910 // Any value, provided by your app
Durch Einschließen von Berechtigungsbereichen in die Anforderung und verwendung von response_type=code+id_token
stellt der authorize
Endpunkt sicher, dass der Benutzer den im scope
Abfrageparameter angegebenen Berechtigungen zugestimmt hat, und gibt Ihre App einen Autorisierungscode zurück, der für ein Zugriffstoken ausgetauscht werden soll.
Erfolgreiche Antwort
Eine erfolgreiche Antwort, die mithilfe von response_mode=form_post
an die redirect_uri
gesendet wird, sieht wie folgt aus:
POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&state=12345
Parameter | BESCHREIBUNG |
---|---|
id_token | Der von der App angeforderte id_token . Sie können die id_token verwenden, um die Identität des Benutzers zu überprüfen und eine Sitzung mit dem Benutzer zu beginnen. |
Code | Der Autorisierungscode, den die App angefordert hat. Die App kann mithilfe des Autorisierungscodes ein Zugriffstoken für die Zielressource anfordern. Authorization_codes sind kurzlebig und laufen in der Regel nach ca. 10 Minuten ab. |
Staat | Wenn in der Anforderung ein Zustandsparameter enthalten ist, sollte derselbe Wert in der Antwort angezeigt werden. Die App sollte überprüfen, ob die Zustandswerte in der Anforderung und Antwort identisch sind. |
Fehlerantwort
Fehlerantworten können auch an den redirect_uri
gesendet werden, damit die App diese angemessen behandeln kann:
POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
error=access_denied&error_description=the+user+canceled+the+authentication
Parameter | BESCHREIBUNG |
---|---|
Fehler | Eine Fehlercodezeichenfolge, die verwendet werden kann, um unterschiedliche Arten auftretender Fehler zu klassifizieren und um auf Fehler zu reagieren. |
Fehlerbeschreibung | Eine spezifische Fehlermeldung, mit der Entwickler die Hauptursache eines Authentifizierungsfehlers identifizieren können. |
Eine Beschreibung der möglichen Fehlercodes und deren empfohlene Clientaktion finden Sie unter Fehlercodes für Autorisierungsendpunktfehler.
Nachdem Sie eine Autorisierungs-code
und eine id_token
erhalten haben, können Sie den Benutzer anmelden und Zugriffstoken in ihrem Namen abrufen. Um den Benutzer anzumelden, müssen Sie die id_token
genau wie oben beschrieben überprüfen. Um Zugriffstoken abzurufen, können Sie die im Abschnitt "Verwenden des Autorisierungscodes zum Anfordern eines Zugriffstokens" beschriebenen Schritte in unserer OAuth-Codeflussdokumentationausführen.
Nächste Schritte
- Erfahren Sie mehr über die Zugriffstoken.
- Erfahren Sie mehr über ,
id_token
und Ansprüche.