Web-App für Benutzeranmeldungen: An- und Abmeldung
Artikel
Erfahren Sie, wie Sie dem Code für Ihre Web-App eine Anmeldefunktion zur Benutzeranmeldung hinzufügen. Anschließend erfahren Sie, wie Sie auch die Abmeldung ermöglichen.
In ASP.NET Core wird für Microsoft Identity Platform-Anwendungen die Schaltfläche Anmelden in Views\Shared\_LoginPartial.cshtml (für eine MVC-App) oder Pages\Shared\_LoginPartial.cshtm (für eine Razor-App) verfügbar gemacht. Sie wird nur angezeigt, wenn der Benutzer sich noch nicht authentifiziert hat. Das heißt, sie wird angezeigt, wenn sich der Benutzer noch nicht angemeldet oder sich zuvor abgemeldet hat. Im Gegensatz dazu wird die Schaltfläche Abmelden angezeigt, wenn der Benutzer bereits angemeldet ist. Beachten Sie, dass der Kontocontroller im NuGet-Paket Microsoft.Identity.Web.UI im Bereich MicrosoftIdentity definiert ist.
In ASP.NET MVC wird die Schaltfläche Anmelden in Views\Shared\_LoginPartial.cshtml verfügbar gemacht. Sie wird nur angezeigt, wenn der Benutzer sich noch nicht authentifiziert hat. Das heißt, sie wird angezeigt, wenn sich der Benutzer noch nicht angemeldet oder sich zuvor abgemeldet hat.
Wenn ein nicht authentifizierter Benutzer die Startseite besucht, leitet die Route index in app.py den Benutzer zur Route login um.
@app.route("/")
def index():
if not (app.config["CLIENT_ID"] and app.config["CLIENT_SECRET"]):
# This check is not strictly necessary.
# You can remove this check from your production code.
return render_template('config_error.html')
if not auth.get_user():
return redirect(url_for("login"))
return render_template('index.html', user=auth.get_user(), version=identity.__version__)
Die Route login ermittelt die geeignete auth_uri und rendert die Vorlage login.html.
@app.route("/login")
def login():
return render_template("login.html", version=identity.__version__, **auth.log_in(
scopes=app_config.SCOPE, # Have user consent to scopes during log-in
redirect_uri=url_for("auth_response", _external=True), # Optional. If present, this absolute URL must match your app's redirect_uri registered in Azure Portal
))
+In ASP.NET wird durch Auswahl der Schaltfläche Anmelden in der Web-App die Aktion SignIn auf dem AccountController-Controller ausgelöst. In früheren Versionen der ASP.NET Core-Vorlagen war der Account-Controller in die Web-App eingebettet. Das ist nicht mehr der Fall, da der Controller jetzt Teil des NuGet-Pakets Microsoft.Identity.Web.UI ist. Weitere Informationen finden Sie unter AccountController.cs.
Dieser Controller behandelt auch die Azure AD B2C-Anwendungen.
In ASP.NET wird die Anmeldung von der SignIn()-Methode auf einem Controller ausgelöst (z. B. AccountController.cs#L16-L23). Diese Methode gehört (im Gegensatz zu den Vorgängen in .NET Core) nicht zum ASP.NET-Framework. Sie sendet eine OpenID-Anmeldeaufforderung, nachdem ein Umleitungs-URI vorgeschlagen wurde.
public void SignIn()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
In Java wird die Abmeldung behandelt, indem der logout-Endpunkt der Microsoft Identity Platform direkt aufgerufen und der Wert post_logout_redirect_uri bereitgestellt wird. Weitere Informationen finden Sie unter AuthPageController.java#L30-L48.
@Controller
public class AuthPageController {
@Autowired
AuthHelper authHelper;
@RequestMapping("/msal4jsample")
public String homepage(){
return "index";
}
@RequestMapping("/msal4jsample/secure/aad")
public ModelAndView securePage(HttpServletRequest httpRequest) throws ParseException {
ModelAndView mav = new ModelAndView("auth_page");
setAccountInfo(mav, httpRequest);
return mav;
}
// More code omitted for simplicity
Wenn Benutzer*innen den Link Anmelden auswählen, der die Route /auth/signin auslöst, übernimmt der Anmeldecontroller die Authentifizierung der Benutzer*innen mit Microsoft Identity Platform.
login(options = {}) {
return async (req, res, next) => {
/**
* MSAL Node library allows you to pass your custom state as state parameter in the Request object.
* The state parameter can also be used to encode information of the app's state before redirect.
* You can pass the user's state in the app, such as the page or view they were on, as input to this parameter.
*/
const state = this.cryptoProvider.base64Encode(
JSON.stringify({
successRedirect: options.successRedirect || '/',
})
);
const authCodeUrlRequestParams = {
state: state,
/**
* By default, MSAL Node will add OIDC scopes to the auth code url request. For more information, visit:
* https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
scopes: options.scopes || [],
redirectUri: options.redirectUri,
};
const authCodeRequestParams = {
state: state,
/**
* By default, MSAL Node will add OIDC scopes to the auth code request. For more information, visit:
* https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
scopes: options.scopes || [],
redirectUri: options.redirectUri,
};
/**
* If the current msal configuration does not have cloudDiscoveryMetadata or authorityMetadata, we will
* make a request to the relevant endpoints to retrieve the metadata. This allows MSAL to avoid making
* metadata discovery calls, thereby improving performance of token acquisition process. For more, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/performance.md
*/
if (!this.msalConfig.auth.cloudDiscoveryMetadata || !this.msalConfig.auth.authorityMetadata) {
const [cloudDiscoveryMetadata, authorityMetadata] = await Promise.all([
this.getCloudDiscoveryMetadata(this.msalConfig.auth.authority),
this.getAuthorityMetadata(this.msalConfig.auth.authority)
]);
this.msalConfig.auth.cloudDiscoveryMetadata = JSON.stringify(cloudDiscoveryMetadata);
this.msalConfig.auth.authorityMetadata = JSON.stringify(authorityMetadata);
}
const msalInstance = this.getMsalInstance(this.msalConfig);
// trigger the first leg of auth code flow
return this.redirectToAuthCodeUrl(
authCodeUrlRequestParams,
authCodeRequestParams,
msalInstance
)(req, res, next);
};
}
redirectToAuthCodeUrl(authCodeUrlRequestParams, authCodeRequestParams, msalInstance) {
return async (req, res, next) => {
// Generate PKCE Codes before starting the authorization flow
const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes();
// Set generated PKCE codes and method as session vars
req.session.pkceCodes = {
challengeMethod: 'S256',
verifier: verifier,
challenge: challenge,
};
/**
* By manipulating the request objects below before each request, we can obtain
* auth artifacts with desired claims. For more information, visit:
* https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest
* https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationcoderequest
**/
req.session.authCodeUrlRequest = {
...authCodeUrlRequestParams,
responseMode: msal.ResponseMode.FORM_POST, // recommended for confidential clients
codeChallenge: req.session.pkceCodes.challenge,
codeChallengeMethod: req.session.pkceCodes.challengeMethod,
};
req.session.authCodeRequest = {
...authCodeRequestParams,
code: '',
};
try {
const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
res.redirect(authCodeUrlResponse);
} catch (error) {
next(error);
}
};
}
/**
* Retrieves cloud discovery metadata from the /discovery/instance endpoint
* @returns
*/
async getCloudDiscoveryMetadata(authority) {
const endpoint = 'https://login.microsoftonline.com/common/discovery/instance';
try {
const response = await axios.get(endpoint, {
params: {
'api-version': '1.1',
'authorization_endpoint': `${authority}/oauth2/v2.0/authorize`
}
});
return await response.data;
} catch (error) {
throw error;
}
}
Wenn der Benutzer den Link Anmelden auswählt, wird er zum Microsoft Identity Platform-Autorisierungsendpunkt weitergeleitet.
Bei einer erfolgreichen Anmeldung wird der Benutzer zur Route auth_response umgeleitet, die den Anmeldevorgang mit auth.complete_loginabschließt, mögliche Fehler rendert und den jetzt authentifizierten Benutzer zur Startseite weiterleitet.
@app.route(app_config.REDIRECT_PATH)
def auth_response():
result = auth.complete_log_in(request.args)
if "error" in result:
return render_template("auth_error.html", result=result)
return redirect(url_for("index"))
Nachdem der Benutzer sich bei Ihrer App angemeldet hat, sollten Sie ihm auch das Abmelden ermöglichen.
Abmeldung
Beim Abmelden von einer Web-App geht es um mehr als um das Entfernen der Informationen zum angemeldeten Konto aus dem Status der Web-App.
Die Web-App muss den Benutzer für die Abmeldung außerdem an den logout-Endpunkt von Microsoft Identity Platform umleiten.
Wenn Ihre Web-App den Benutzer an den logout-Endpunkt umleitet, löscht dieser Endpunkt die Sitzung des Benutzers aus dem Browser. Wenn Ihre App nicht den logout-Endpunkt erreicht hat, kann sich der Benutzer erneut bei Ihrer App authentifizieren, ohne die Anmeldeinformationen erneut eingeben zu müssen. Der Grund hierfür ist, dass er über eine gültige Sitzung für einmaliges Anmelden mit Microsoft Identity Platform verfügt.
Bei der Anwendungsregistrierung registrieren Sie eine Front-Channel-Abmelde-URL. In unserem Tutorial haben Sie https://localhost:44321/signout-oidc im Feld Front-Channel-Abmelde-URL auf der Seite Authentifizierung registriert. Weitere Informationen finden Sie unter Registrieren der webApp-App.
Bei der Anwendungsregistrierung müssen Sie keine zusätzliche Front-Channel-Abmelde-URL registrieren. Die App wird über die Haupt-URL zurückgerufen.
Bei der Anwendungsregistrierung ist keine Front-Channel-Abmelde-URL erforderlich.
Bei der Anwendungsregistrierung ist keine Front-Channel-Abmelde-URL erforderlich.
Bei der Anwendungsregistrierung müssen Sie keine zusätzliche Front-Channel-Abmelde-URL registrieren. Die App wird über die Haupt-URL zurückgerufen.
In ASP.NET wird durch Auswahl der Schaltfläche Abmelden in der Web-App die Aktion SignOut auf dem AccountController-Controller ausgelöst (siehe unten).
In ASP.NET MVC wird die Abmeldeschaltfläche in Views\Shared\_LoginPartial.cshtml verfügbar gemacht. Sie wird nur angezeigt, wenn ein authentifiziertes Konto vorhanden ist. Das heißt, sie wird angezeigt, wenn sich der Benutzer zuvor angemeldet hat.
In früheren Versionen der ASP.NET Core-Vorlagen war der Account-Controller in die Web-App eingebettet. Das ist nicht mehr der Fall, da der Controller jetzt Teil des NuGet-Pakets Microsoft.Identity.Web.UI ist. Weitere Informationen finden Sie unter AccountController.cs.
Sie legt einen OpenID-Umleitungs-URI auf /Account/SignedOut fest, damit der Controller zurückgerufen wird, wenn Microsoft Entra ID die Abmeldung abgeschlossen hat.
Sie ruft Signout() auf, damit die OpenID Connect-Middleware den logout-Endpunkt der Microsoft Identity Platform kontaktieren kann. Der Endpunkt führt dann folgende Aktionen aus:
Er löscht den Sitzungscookie im Browser.
Er ruft den Umleitungs-URI nach der Abmeldung zurück. Standardmäßig zeigt der Umleitungs-URI nach der Abmeldung SignedOut.cshtml.cs an. Diese Seite wird auch als Teil von Microsoft.Identity.Web bereitgestellt.
In ASP.NET wird die Abmeldung von der SignOut()-Methode auf einem Controller ausgelöst (z. B. AccountController.cs#L25-L31). Diese Methode gehört im Gegensatz zu den Vorgängen in .NET Core nicht zum ASP.NET-Framework. Sie hat folgende Aufgaben:
Sie sendet eine OpenID-Abmeldeaufforderung.
Sie löscht den Cache.
Sie leitet auf die gewünschte Seite um.
/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
public void SignOut()
{
HttpContext.GetOwinContext()
.Authentication
.SignOut(CookieAuthenticationDefaults.AuthenticationType);
Response.Redirect("/");
}
In Java wird die Abmeldung behandelt, indem der logout-Endpunkt der Microsoft Identity Platform direkt aufgerufen und der Wert post_logout_redirect_uri bereitgestellt wird. Weitere Informationen finden Sie unter AuthPageController.java#L50-L60.
Wenn Benutzer*innen die Schaltfläche Abmelden auswählen, löst die App die Route /auth/signout aus, die die Sitzung zerstört und den Browser an den Abmeldeendpunkt von Microsoft Identity Platform umleitet.
logout(options = {}) {
return (req, res, next) => {
/**
* Construct a logout URI and redirect the user to end the
* session with Azure AD. For more information, visit:
* https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc#send-a-sign-out-request
*/
let logoutUri = `${this.msalConfig.auth.authority}/oauth2/v2.0/`;
if (options.postLogoutRedirectUri) {
logoutUri += `logout?post_logout_redirect_uri=${options.postLogoutRedirectUri}`;
}
req.session.destroy(() => {
res.redirect(logoutUri);
});
}
}
Wenn der Benutzer die Schaltfläche Abmelden auswählt, löst die App die Route logout aus, die den Browser an den Abmeldeendpunkt der Microsoft Identity Platform umleitet.
Mit der OpenID Connect-Middleware von ASP.NET Core kann Ihre App den Aufruf an den logout-Endpunkt der Microsoft Identity Platform durch die Bereitstellung des OpenID Connect-Ereignisses OnRedirectToIdentityProviderForSignOut abfangen. Dies erfolgt automatisch durch Microsoft.Identity.Web (indem Konten gelöscht werden, wenn Ihre Web-App Web-APIs aufruft).
In ASP.NET delegieren Sie die Ausführung der Abmeldung an die Middleware, indem Sie das Sitzungscookie löschen:
public class AccountController : Controller
{
...
public void EndSession()
{
Request.GetOwinContext().Authentication.SignOut();
Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
this.HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
}
}
Im Java-Schnellstart zeigt der Umleitungs-URI nach der Abmeldung nur die Seite „index.html“ an.
Im Node-Schnellstart wird der Umleitungs-URI nach der Abmeldung verwendet, um den Browser zurück zur Beispielstartseite umzuleiten, nachdem die Benutzer*innen den Abmeldevorgang mit Microsoft Identity Platform abgeschlossen haben.
In der Python-Schnellstartanleitung zeigt die URI für die Umleitung nach dem Logout nur die Seite index.html an.
Protocol
Weitere Informationen zum Abmelden finden Sie in der Protokolldokumentation, die über OpenID Connect verfügbar ist.
Nächste Schritte
Erfahren Sie mehr, indem Sie in der folgenden mehrteiligen Tutorialreihe eine ASP.NET Core-Webanwendung für die Anmeldung von Benutzern erstellen