Dotyczy:
Najemcy siły roboczej
Najemcy zewnętrzni (dowiedz się więcej)
Dowiedz się, jak dodać logowanie do kodu aplikacji internetowej, która loguje użytkowników. Następnie dowiedz się, jak ich wylogować.
Logowanie
Logowanie składa się z dwóch części:
- Przycisk logowania na stronie HTML
- Akcja logowania w pliku code-behind w kontrolerze
W ASP.NET Core, w przypadku aplikacji na platformie tożsamości Microsoft, przycisk Zaloguj jest uwidoczniony Views\Shared\_LoginPartial.cshtml
(dla aplikacji MVC) lub Pages\Shared\_LoginPartial.cshtm
(dla aplikacji Razor). Jest on wyświetlany tylko wtedy, gdy użytkownik nie jest uwierzytelniony. Oznacza to, że jest wyświetlany, gdy użytkownik jeszcze się nie zalogował lub nie wylogował. Wręcz przeciwnie, przycisk Wyloguj jest wyświetlany, gdy użytkownik jest już zalogowany. Kontroler konta jest zdefiniowany w pakiecie NuGet Microsoft.Identity.Web.UI, w obszarze nazwanym MicrosoftIdentity
<ul class="navbar-nav">
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<span class="navbar-text text-dark">Hello @User.Identity.Name!</span>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
</li>
}
</ul>
W ASP.NET MVC przycisk „Zaloguj się” jest dostępny w . Jest on wyświetlany tylko wtedy, gdy użytkownik nie jest uwierzytelniony. Oznacza to, że jest wyświetlany, gdy użytkownik jeszcze się nie zalogował lub nie wylogował.
@if (Request.IsAuthenticated)
{
// Code omitted code for clarity
}
else
{
<ul class="nav navbar-nav navbar-right">
<li>@Html.ActionLink("Sign in", "SignIn", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
</ul>
}
W przewodniku szybkiego startu Java, przycisk logowania znajduje się w pliku main/resources/templates/index.html.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>HomePage</title>
</head>
<body>
<h3>Home Page</h3>
<form action="/msal4jsample/secure/aad">
<input type="submit" value="Login">
</form>
</body>
</html>
W przewodniku szybkiego startu Node.js kod przycisku logowania znajduje się w pliku szablonu index.hbs.
<p>Welcome to {{title}}</p>
<a href="/auth/signin">Sign in</a>
Ten szablon jest udostępniany za pośrednictwem głównej (indeksowej) trasy aplikacji.
var express = require('express');
var router = express.Router();
router.get('/', function (req, res, next) {
res.render('index', {
title: 'MSAL Node & Express Web App',
isAuthenticated: req.session.isAuthenticated,
username: req.session.account?.username,
});
});
W przewodniku szybkiego startu Pythona kod linku logowania znajduje się w pliku szablonu login.html.
<ul><li><a href='{{ auth_uri }}'>Sign In</a></li></ul>
Gdy nieuwierzytelniony użytkownik odwiedza stronę główną, index
ścieżka w app.py przekierowuje użytkownika do login
ścieżki.
@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__)
Ścieżka login
określa właściwy auth_uri
i renderuje szablon 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
))
SignIn
działanie kontrolera
W ramach ASP.NET wybranie przycisku Zalogowanie w aplikacji internetowej powoduje wyzwolenie akcji SignIn
na kontrolerze AccountController
. W poprzednich wersjach szablonów ASP.NET Core, kontroler był osadzony w aplikacji internetowej. Tak już nie jest, ponieważ kontroler jest teraz częścią pakietu NuGet Microsoft.Identity.Web.UI . Aby uzyskać szczegółowe informacje, zobacz AccountController.cs .
Ten kontroler obsługuje również aplikacje usługi Azure AD B2C.
W ASP.NET logowanie jest wyzwalane z SignIn()
metody na kontrolerze (na przykład AccountController.cs#L16-L23). Ta metoda nie jest częścią programu .NET Framework (w przeciwieństwie do tego, co dzieje się w ASP.NET Core). Wysyła wyzwanie logowania OpenID po zaproponowaniu przekierowania URI.
public void SignIn()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
W Javie, wylogowanie jest obsługiwane przez bezpośrednie wywołanie punktu końcowego logout
platformy tożsamości Microsoft i podanie wartości post_logout_redirect_uri
. Aby uzyskać szczegółowe informacje, zobacz 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
Gdy użytkownik wybierze link Zaloguj się, który wyzwala ścieżkę /auth/signin
, kontroler logowania przejmuje kontrolę, aby uwierzytelnić użytkownika przy użyciu platformy tożsamości Microsoft.
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;
}
}
Gdy użytkownik wybierze link Zaloguj się, zostanie przeniesiony do punktu końcowego autoryzacji platformy tożsamości Microsoft.
Pomyślne zalogowanie przekierowuje użytkownika do auth_response
ścieżki, która kończy proces logowania przy użyciu auth.complete_login
, renderuje błędy, jeśli występują, i przekierowuje teraz uwierzytelnionego użytkownika na stronę główną.
@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"))
Po zalogowaniu się użytkownika do aplikacji należy włączyć ich wylogowanie.
Wyloguj się
Wylogowywanie z aplikacji internetowej wymaga więcej niż usunięcia informacji o zalogowanym koncie ze stanu aplikacji internetowej.
Aplikacja internetowa musi również przekierować użytkownika do punktu końcowego Platforma tożsamości Microsoftlogout
, aby się wylogować.
Gdy aplikacja internetowa przekierowuje użytkownika do punktu końcowego logout
, ten punkt końcowy wyczyści sesję użytkownika z przeglądarki. Jeśli aplikacja nie przejdzie do punktu końcowego logout
, użytkownik może ponownie uwierzytelnić aplikację bez konieczności ponownego wprowadzania poświadczeń. Przyczyną jest to, że będą mieć prawidłową sesję jednokrotnego logowania z platformą tożsamości Microsoft.
Aby dowiedzieć się więcej, zobacz sekcję Wysyłanie żądania wylogowania w dokumentacji platformy tożsamości Microsoft i protokołu OpenID Connect.
Rejestrowanie aplikacji
Podczas rejestracji aplikacji rejestrujesz adres URL wylogowywania połączenia front-channel. W naszym samouczku zarejestrowałeś https://localhost:44321/signout-oidc
w polu Adres URL wylogowywania kanału frontowego na stronie Uwierzytelnianie. Aby uzyskać szczegółowe informacje, zobacz Rejestrowanie aplikacji internetowej.
Podczas rejestracji aplikacji nie musisz rejestrować dodatkowego adresu URL wylogowywania kanału frontowego. Aplikacja jest wywoływana z powrotem pod głównym adresem URL.
W rejestracji aplikacji nie jest wymagany adres URL wylogowania front-channel.
W rejestracji aplikacji nie jest wymagany adres URL wylogowania front-channel.
Podczas rejestracji aplikacji nie musisz rejestrować dodatkowego adresu URL wylogowywania kanału frontowego. Aplikacja jest wywoływana z powrotem pod głównym adresem URL.
W ASP.NET wybranie przycisku Wyloguj w aplikacji internetowej wyzwala akcję SignOut
na kontrolerze AccountController
(patrz poniżej)
<ul class="navbar-nav">
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<span class="navbar-text text-dark">Hello @User.Identity.Name!</span>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
</li>
}
</ul>
W ASP.NET MVC przycisk wyloguj się jest uwidoczniony w Views\Shared\_LoginPartial.cshtml
. Jest on wyświetlany tylko wtedy, gdy istnieje uwierzytelnione konto. Oznacza to, że jest wyświetlany, gdy użytkownik wcześniej się zalogował.
@if (Request.IsAuthenticated)
{
<text>
<ul class="nav navbar-nav navbar-right">
<li class="navbar-text">
Hello, @User.Identity.Name!
</li>
<li>
@Html.ActionLink("Sign out", "SignOut", "Account")
</li>
</ul>
</text>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li>@Html.ActionLink("Sign in", "SignIn", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
</ul>
}
W naszym przewodniku "Szybki start języka Java" przycisk "Wyloguj się" znajduje się w pliku main/resources/templates/auth_page.html.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<form action="/msal4jsample/sign_out">
<input type="submit" value="Sign out">
</form>
...
{{#if isAuthenticated }}
<a href="/auth/signout">Sign out</a>
W przewodniku Szybki start do Pythona przycisk wyloguj się znajduje się w pliku templates/index.html.
<li><a href="/logout">Logout</a></li>
SignOut
działanie kontrolera
W poprzednich wersjach szablonów ASP.NET Core, kontroler był osadzony w aplikacji internetowej. Tak już nie jest, ponieważ kontroler jest teraz częścią pakietu NuGet Microsoft.Identity.Web.UI . Aby uzyskać szczegółowe informacje, zobacz AccountController.cs .
Ustawia URI przekierowania OpenID na /Account/SignedOut
, aby kontroler został ponownie wywołany po zakończeniu wylogowania się przez Microsoft Entra ID.
Wywołuje Signout()
, co umożliwia oprogramowaniu pośredniczącemu OpenID Connect kontakt z punktem końcowym platformy tożsamości Microsoft logout
. Następnie punkt końcowy:
- Czyści plik cookie sesji z przeglądarki.
- Przywraca URI przekierowania po wylogowaniu. Domyślnie URI przekierowania po wylogowaniu wyświetla stronę SignedOut.cshtml.cs. Ta strona jest również udostępniana jako część Microsoft.Identity.Web.
W ASP.NET wylogowanie jest inicjowane za pomocą metody SignOut()
w kontrolerze (na przykładzie AccountController.cs#L25-L31). Ta metoda nie jest częścią programu .NET Framework, w przeciwieństwie do tego, co dzieje się w ASP.NET Core. Ono:
- Wysyła wyzwanie do wylogowania OpenID.
- Czyści pamięć podręczną.
- Przekierowuje do żądanej strony.
/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
public void SignOut()
{
HttpContext.GetOwinContext()
.Authentication
.SignOut(CookieAuthenticationDefaults.AuthenticationType);
Response.Redirect("/");
}
W Javie, wylogowanie jest obsługiwane przez bezpośrednie wywołanie punktu końcowego logout
platformy tożsamości Microsoft i podanie wartości post_logout_redirect_uri
. Aby uzyskać szczegółowe informacje, zobacz AuthPageController.java#L50-L60.
@RequestMapping("/msal4jsample/sign_out")
public void signOut(HttpServletRequest httpRequest, HttpServletResponse response) throws IOException {
httpRequest.getSession().invalidate();
String endSessionEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/logout";
String redirectUrl = "http://localhost:8080/msal4jsample/";
response.sendRedirect(endSessionEndpoint + "?post_logout_redirect_uri=" +
URLEncoder.encode(redirectUrl, "UTF-8"));
}
Gdy użytkownik wybierze przycisk Wyloguj się, aplikacja wyzwala ścieżkę /auth/signout
, która niszczy sesję i przekierowuje przeglądarkę do punktu końcowego wylogowania platformy tożsamości Microsoft.
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);
});
}
}
Gdy użytkownik wybierze Wyloguj się, aplikacja wyzwala trasę logout
, która przekierowuje przeglądarkę do punktu końcowego wylogowania się z platformy tożsamości firmy Microsoft.
@app.route("/logout")
def logout():
return redirect(auth.log_out(url_for("index", _external=True)))
Przechwytywanie wywołania do punktu końcowego logout
Identyfikator URI po wylogowaniu umożliwia aplikacjom uczestnictwo w wylogowaniu globalnym.
Oprogramowanie pośredniczące ASP.NET Core OpenID Connect umożliwia aplikacji przechwycenie wywołania do punktu końcowego platformy tożsamości Microsoft logout
poprzez zdarzenie OpenID Connect o nazwie OnRedirectToIdentityProviderForSignOut
. Jest to obsługiwane automatycznie przez microsoft.Identity.Web (co powoduje wyczyszczenie kont w przypadku, gdy aplikacja internetowa wywołuje internetowe interfejsy API).
W ASP.NET delegujesz oprogramowanie pośredniczące, aby wykonać wylogowanie, czyszcząc plik cookie sesji:
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);
}
}
W przewodniku "Szybki start" dla języka Java, identyfikator URI przekierowania po wylogowaniu po prostu wyświetla stronę index.html.
W przewodniku szybki start dla Node.js identyfikator URI przekierowania po wylogowaniu jest używany do przekierowywania przeglądarki z powrotem do przykładowej strony głównej po zakończeniu procesu wylogowania za pomocą platformy tożsamości Microsoft.
W przewodniku "Szybki Start" języka Python, URI przekierowania po wylogowaniu po prostu wyświetla stronę index.html.
Protokół
Jeśli chcesz dowiedzieć się więcej na temat wylogowania, przeczytaj dokumentację protokołu dostępną w witrynie OpenID Connect.
Następne kroki
Dowiedz się więcej, tworząc aplikację internetową ASP.NET Core, która umożliwia logowanie użytkowników w poniższej wieloczęściowej serii samouczków
Zapoznaj się z przykładami aplikacji internetowych platformy tożsamości Microsoft