Application web qui connecte les utilisateurs : Se connecter et se déconnecter
Article
Découvrez comment ajouter une connexion au code de votre application web pour connecter les utilisateurs. Ensuite, découvrez comment les autoriser à se déconnecter.
Connexion
La connexion comprend deux parties :
Le bouton de connexion dans la page HTML
L’action de connexion dans le code-behind du contrôleur
Dans ASP.NET Core, pour les applications de plateforme d’identité Microsoft, le bouton Se connecter est exposé dans Views\Shared\_LoginPartial.cshtml (pour une application MVC) ou Pages\Shared\_LoginPartial.cshtm (pour une application Razor). Elles s’affichent uniquement quand l’utilisateur n’est pas authentifié. Autrement dit, il s’affiche lorsque l’utilisateur ne s’est pas encore connecté ou qu’il s’est déconnecté. Au contraire, le bouton Se déconnecter s’affiche lorsque l’utilisateur est déjà connecté. Notez que le contrôleur de compte est défini dans le package NuGet Microsoft.Identity.Web.UI, dans la zone nommée MicrosoftIdentity
Dans ASP.NET MVC, le bouton Se connecter est exposé dans Views\Shared\_LoginPartial.cshtml. Elles s’affichent uniquement quand l’utilisateur n’est pas authentifié. Autrement dit, il s’affiche lorsque l’utilisateur ne s’est pas encore connecté ou qu’il s’est déconnecté.
Lorsqu’un utilisateur non authentifié visite la page d’accueil, l’itinéraire index dans app.py redirige l’utilisateur vers l’itinéraire login.
@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__)
L’itinéraire login détermine le modèle approprié auth_uri et affiche le modèle 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
))
Dans ASP.NET, sélectionner le bouton Connexion de l’application web déclenche l’action SignIn sur le contrôleur AccountController. Dans les versions précédentes des modèles ASP.NET Core, le contrôleur Account était incorporé avec l’application web. Ce n’est plus le cas, car le contrôleur fait maintenant partie du package NuGet Microsoft.Identity.Web.UI. Pour plus d’informations, consultez AccountController.cs.
Ce contrôleur gère également les applications Azure AD B2C.
Dans ASP.NET, la connexion est déclenchée par la méthode SignIn() sur un contrôleur (par exemple, AccountController.cs#L16-L23). Cette méthode ne fait pas partie du .NET Framework (contrairement à ce qui se passe dans ASP.NET Core). Envoi d’une demande de connexion OpenID après avoir proposé un URI de redirection.
public void SignIn()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
Dans Java, la déconnexion est gérée en appelant directement le point de terminaison logout de la plateforme d’identités Microsoft et en fournissant la valeur post_logout_redirect_uri. Pour plus d’informations, consultez 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
Lorsque l’utilisateur sélectionne le lien Connexion, qui déclenche l’itinéraire /auth/signin, le contrôleur de connexion prend le relais pour authentifier l’utilisateur avec la plateforme d’identité 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;
}
}
Lorsque l’utilisateur sélectionne le lien Se connecter, il est dirigé vers le point de terminaison d’autorisation de la plateforme d’identités Microsoft.
Une connexion réussie redirige l’utilisateur vers l’itinéraire auth_response, qui termine le processus de connexion à l’aide de auth.complete_login, affiche les erreurs le cas échéant et redirige l’utilisateur désormais authentifié vers la page d’accueil.
@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"))
Une fois que l’utilisateur est connecté à votre application, vous voudrez leur donner la possibilité de se déconnecter.
Se déconnecter
La déconnexion d’une application web ne consiste pas seulement à supprimer les informations sur le compte connecté de l’état de l’application web.
L’application web doit également rediriger l’utilisateur vers le point de terminaison logout de la plateforme d’identités Microsoft pour suivre la procédure de déconnexion.
Lorsque votre application web redirige l’utilisateur vers le point de terminaison logout, ce dernier efface la session de l’utilisateur dans le navigateur. Si votre application n’a pas atteint le point de terminaison logout, l’utilisateur se réauthentifie auprès de votre application sans entrer à nouveau ses informations d’identification. La raison en est qu’il disposera d’une session d’authentification unique valide auprès de la plateforme d’identités Microsoft.
Lors de l’inscription d’application, vous inscrivez une URL de déconnexion du canal frontal. Dans notre tutoriel, vous avez inscrit https://localhost:44321/signout-oidc dans le champ URL de déconnexion du canal frontal de la page Authentification. Pour plus d’informations, voir Inscrire l’application web.
Au cours de l’inscription d’application, vous n’avez pas besoin d’inscrire d’URL de déconnexion du canal frontal supplémentaire. L’application est rappelée sur son URL principale.
Aucune URL de déconnexion du canal frontal n’est requise dans l’inscription d’application.
Aucune URL de déconnexion du canal frontal n’est requise dans l’inscription d’application.
Au cours de l’inscription d’application, vous n’avez pas besoin d’inscrire d’URL de déconnexion du canal frontal supplémentaire. L’application est rappelée sur son URL principale.
Dans ASP.NET MVC, le bouton de déconnexion est exposé dans Views\Shared\_LoginPartial.cshtml. Cela s’affiche uniquement lorsqu’il y a un compte authentifié. Autrement dit, cela s’affiche lorsque l’utilisateur s’est connecté précédemment.
Dans les versions précédentes des modèles ASP.NET Core, le contrôleur Account était incorporé avec l’application web. Ce n’est plus le cas, car le contrôleur fait maintenant partie du package NuGet Microsoft.Identity.Web.UI. Pour plus d’informations, consultez AccountController.cs.
Définir un URI de redirection OpenID sur /Account/SignedOut afin que le contrôleur soit rappelé quand Microsoft Entra ID a effectué la déconnexion.
Appeler Signout(), ce qui permet à l’intergiciel OpenID Connect de contacter le point de terminaison logout de la plateforme d’identités Microsoft. Ensuite, le point de terminaison :
efface le cookie de session du navigateur.
Rappelle l’URI de redirection après déconnexion. Par défaut, l’URI de redirection après déconnexion affiche la page de la vue déconnectée SignedOut.cshtml.cs. Cette page est également fournie dans le cadre de Microsoft.Identity.Web.
Dans ASP.NET, la déconnexion est déclenchée par la méthode SignOut() sur un contrôleur (par exemple, AccountController.cs#L25-L31). Cette méthode ne fait pas partie du .NET Framework, contrairement à ce qui se passe dans ASP.NET Core. Elle effectue les actions suivantes :
Elle envoie une demande de déconnexion OpenID.
Elle efface le cache.
Effectue une redirection vers la page souhaitée.
/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
public void SignOut()
{
HttpContext.GetOwinContext()
.Authentication
.SignOut(CookieAuthenticationDefaults.AuthenticationType);
Response.Redirect("/");
}
Dans Java, la déconnexion est gérée en appelant directement le point de terminaison logout de la plateforme d’identités Microsoft et en fournissant la valeur post_logout_redirect_uri. Pour plus d’informations, consultez AuthPageController.java#L50-L60.
Lorsque l’utilisateur sélectionne le bouton Déconnexion, l’application déclenche l’itinéraire /auth/signout, ce qui détruit la session et redirige le navigateur vers le point de terminaison de déconnexion de la plateforme d’identité 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);
});
}
}
Lorsque l’utilisateur sélectionne Déconnexion, l’application déclenche l’itinéraire logout, ce qui redirige le navigateur vers le point de terminaison de déconnexion de la plateforme d’identité Microsoft.
L’intergiciel OpenID Connect ASP.NET Core permet à votre application d’intercepter l’appel au point de terminaison logout de la plateforme d’identités Microsoft en fournissant un événement OpenID Connect nommé OnRedirectToIdentityProviderForSignOut. Cela est géré automatiquement par Microsoft.Identity.Web (qui efface les comptes dans le cas où votre application web appelle des API web)
Dans ASP.NET, vous déléguez à l’intergiciel (middleware) l’exécution de la déconnexion, en effaçant le cookie de session :
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);
}
}
Dans le guide de démarrage rapide Java, l’URI de redirection post-déconnexion affiche uniquement la page index.html.
Dans le guide de démarrage rapide de Node, l’URI de redirection post-déconnexion est utilisé pour rediriger le navigateur vers l’exemple de page d’accueil une fois que l’utilisateur a terminé le processus de déconnexion avec la plateforme d’identité Microsoft.
Dans le démarrage rapide Python, l’URI de redirection post-déconnexion affiche uniquement la page index.html.
Protocol
Pour en savoir plus sur la déconnexion, voir la documentation du protocole, disponible dans OpenID Connect.
Étapes suivantes
Découvrez plus d’informations en créant une application web ASP.NET Core qui connecte les utilisateurs dans cette série de didacticiels en plusieurs parties.