web-dev-qa-db-fra.com

IdentityServer4 PostLogoutRedirectUri

Je suis confus quant à la façon dont cela est utilisé.

La plupart des exemples que j'ai vus l'ont donné comme "/ signout-callback-oidc". Cela semble indiquer qu'il utilise le middleware OIDC dans le processus. Et si je veux revenir à une page client spécifique?

La redirection automatique ne fonctionne pas lorsque j'ai défini la propriété AccountOptions.cs d'IdentityServer sur AutomaticRedirectAfterSignOut sur true. De plus, lors de la déconnexion, je ne reçois pas le PostLogoutRedirectUri du client.

Alors, ce lien est-il censé aller vers le middleware OIDC, ou est-il disponible pour une redirection vers le client?

8
JakeJ

Votre client doit être configuré pour demander le rappel à l'un de ces URI dans le cadre du flux de déconnexion initié par le client.

Les clients IS4 peuvent être configurés avec des listes d'URI de redirection autorisés pour la connexion et la déconnexion, ce qui, je suppose, est l'endroit où vous voyez /signout-callback-oidc - si je me souviens bien, les documents ou peut-être le code Quickstart l'utilisent, mais ce nom d'URI n'a rien de spécial. (Pour autant que je sache, ce n'est pas une norme OIDC, ni un nom "bien connu", ni rien de ce genre.)

La pièce manquante du puzzle est de configurer OIDC dans l'application cliente. Vous n'avez pas mentionné le type d'application du côté client, mais dans ASP.NET Core, c'est une option nommée SignedOutCallbackPath sur le service AddOpenIdConnect:

services.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";
    options.Authority = appConfig["OidcAuthority"];
    options.ClientId = appConfig["OidcClientId"];
    options.ClientSecret = appConfig["OidcClientSecret"];
    // etc

    options.SignedOutCallbackPath = "/jake-says-goodbye";
});

Cela entraîne l'implémentation OIDC pour ajouter une propriété à la demande de déconnexion identifiant cet URI de redirection. Tant que votre application s'identifie correctement, comme brièvement mentionné dans la documentation ici , et tant que /jake-says-goodbye est l'un des URI de redirection post-déconnexion approuvés du côté IS4, vous devriez obtenir le rappel que vous attendez.

(Je mentionne spécifiquement l'identification "correcte" car, sur la base des questions github que j'ai vues, il semble que cela pourrait être plus difficile à gérer pour une application cliente SPA basée sur JS par rapport à toutes les choses utiles que MVC fait en arrière-plan pour gérer le serveur). interaction OIDC vers le serveur. Je ne peux pas en parler car je n'ai pas encore eu besoin d'implémenter de clients SPA avec IS4.)

6
McGuireV10

Le problème est que vous devez définir un paramètre très spécifique pour que PostLogoutRedirectUri ne s'affiche pas comme nul du côté d'IdentityServer, et tester l'une des options entraîne d'avoir à parcourir une tonne de façons de le définir, la plupart d'entre elles résultant toujours en null. Étant donné que j'utilise un ancien client avec IdentityServer4 (pour permettre aux webapps .NET 4.x de s'authentifier via IdentityServer4, ne peut pas facilement utiliser .NET Core avec ces projets - heureusement, IdentityServer4 est toujours compatible avec l'ancien code client), l'action qui déclenche la déconnexion a deux choses pertinentes (et vous trouverez une tonne d'exemples de code qui ne fonctionneront pas pour vous avec MVC dans .NET 4.x):

Utilisez la méthode signout () dans cet exemple de référentiel github (l'exemple de client IdentityServer3 MVC Owin): https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/MVC%20OWIN% 20Client/Controllers/HomeController.cs Vous pouvez déclencher cette action à partir d'un bouton dans une vue.

Cela sera intercepté par le middleware Owin du client si vous faites cela: https://github.com/IdentityServer/IdentityServer3/issues/2687#issuecomment-194739035 Je n'ai pas utilisé le bit de message stocké, et j'ai ajouté le paramètre PostLogoutRedirectUri d'une manière que le modèle LogoutRequest d'IdentityServer4 ne supprimerait pas avec cette ligne dans le même segment:

n.ProtocolMessage.PostLogoutRedirectUri = " http: // myredirectaddress/ActionToDoOnceReturned "; Vous devez vous assurer que ce qui précède correspond à PostLogoutRedirectUri du client dans la configuration client du côté IdentityServer, sinon il sera à nouveau nul, et vous l'auriez manqué parmi tous les autres paramètres. Par exemple, ces méthodes de définition de PostLogoutRedirectUri NE fonctionnent PAS: n.ProtocolMessage.SetParameter ("PostLogoutRedirectURI", "some URL"); n.ProtocolMessage.SetParameter ("PostLogoutUri", "une autre URL"); n.ProtocolMessage.SetParameter ("PostLogoutRedirectUri", "encore une autre URL qui sera ignorée par IdentityServer4");

De là, vous partez pour les courses car PostLogoutRedirectUri n'est plus nul. Il existe quelques autres considérations: consultez AccountOptions dans le dossier du contrôleur IdentityServer. J'ai défini AutomaticRedirectAfterSignout sur true (cela est utilisé par Javascript dans la page de déconnexion finale d'IdSrv - s'il est défini, le script utilise PostLogoutRedirectUri pour renvoyer l'utilisateur au client). Il y a aussi une option pour afficher une invite de confirmation de déconnexion, qui si vous voulez réellement afficher, assurez-vous de ne PAS définir l'indicateur de jeton d'ID dans Owin (c'est juste à côté de l'endroit où nous définissons PostLogoutRedirectUri/la partie qui est déclenchée par des demandes de déconnexion ). Si vous effectuez ces deux opérations, AccountServices.BuildLogoutViewModel renverra l'invite à l'utilisateur lorsqu'il sera appelé par la méthode AccountController.logout (). Merci aaronR pour la réponse à mon autre question concernant cette partie:
déconnexion IdentityServer4 (l'astuce de jeton d'identification indique à IdentityServer que la demande de déconnexion a été autorisée et non une personne malveillante essayant de harceler votre système/déconnecter les utilisateurs, IdSrv demandera à l'utilisateur une confirmation si elle est non fourni).

Enfin, si vous êtes confus par ce qui se passe du côté IdentityServer lors de la déconnexion et pourquoi il déclenche à plusieurs reprises la même méthode:

La première fois, il est appelé à partir du middleware Owin du client (le morceau de code ci-dessus qui est déclenché après l'action Signout ()).

Il utilise AccountService pour créer un modèle de vue à retourner à l'utilisateur pour confirmation de déconnexion.

Il se déclenche à nouveau lorsque l'utilisateur clique sur Oui sur cette page.

Il passe à nouveau par la méthode de service de compte, qui cette fois définit le booléen pour afficher la confirmation de déconnexion sur faux.

Il appelle la deuxième méthode de déconnexion, celle avec le modèle de vue qui est transmise.

Celui-ci déclenche la déconnexion du fournisseur d'identité externe.

Le fournisseur d'identité externe renvoie le contrôle à la déconnexion, ce qui entraîne son rappel, appelant à nouveau la deuxième méthode de déconnexion.

Enfin, il renverra l'utilisateur à la page de déconnexion d'IdentityServer. Si PostLogoutRedirectUri est défini et AutomaticRedirectAfterSignOut est vrai, il y a du javascript sur cette page qui lui transmet automatiquement le navigateur de l'utilisateur.

En raison du fait d'avoir deux projets à déboguer à la fois et de toutes ces façons possibles de définir la redirection (qui doivent également correspondre à la configuration côté client/serveur afin de ne pas être nulle), il peut être facile de se confondre.

3
JakeJ

Aperçu

Lors de la configuration d'IdentityServer (en supposant qu'il s'agit d'une application distincte), il y a deux paramètres dans la configuration pour un client accédant: RedirectUris et PostLogoutRedirectUris. Ceux-ci correspondent à ce qui se passe après une connexion ou une déconnexion d'un utilisateur contre le système IdentityServer .

Étant donné que votre application cliente a probablement ses propres cookies (ou jetons JWT, ou quoi que ce soit qu'elle utilise pour maintenir une session utilisateur), elle doit savoir quand IdentityServer a traité la connexion et rendu les données utilisateur disponibles.

Le middleware ASP.NET OpenID Connect par défaut le fait avec yourapp.com/signin-oidc et yourapp.com/signout-callback-oidc points de terminaison pour intercepter et gérer le transfert de connexion/déconnexion depuis IdentityServer. Ces points de terminaison n'ont rien à voir avec le protocole OpenID et peuvent être définis sur tout ce que vous voulez si vous avez votre propre gestionnaire d'authentification, mais si vous utilisez le middleware par défaut, vous devez les définir dans la configuration IdentityServer.

Option de configuration

Cependant, si vous souhaitez toujours rediriger un utilisateur après la déconnexion d'OpenID Connect est terminée, il existe une option spécifiquement pour cela:

services.AddOpenIdConnect(options => 
{
     // your other options...

     options.SignedOutRedirectUri = "/some-page-after-oidc-logout";
});

https://docs.Microsoft.com/en-us/dotnet/api/Microsoft.aspnetcore.authentication.openidconnect.openidconnectoptions.signedoutredirecturi

2
Mani Gandham

Je veux partager comment j'ai résolu le problème avec la valeur null PostLogoutRedirectUri. J'ai toujours eu une valeur PostLogoutRedirectUri nulle dans le contexte de déconnexion jusqu'à ce que j'ajoute la valeur SignInScheme du côté client mvc. Ces paramètres d'authentification côté client MVC fonctionnent pour moi:

var authenticationBuilder = services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
});

authenticationBuilder.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.Cookie.Name = "identity_server_mvc";
});

authenticationBuilder.AddOpenIdConnect("oidc", options =>
{
    options.Authority = "{IDENTITY_SERVER_URL}";
    options.ClientId = "mvc";
    options.SaveTokens = true;
    options.SignInScheme = "Cookies";
});

Vous devez également vous assurer que vous avez ajouté la valeur PostLogoutRedirectUri à la configuration client du côté Identity Server:

new Client
{
    ClientId = "mvc",
    AllowedGrantTypes = GrantTypes.Implicit,

    RedirectUris           = { "{CLIENT_URL}/signin-oidc" },
    PostLogoutRedirectUris = { "{CLIENT_URL}/signout-callback-oidc" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile
    }
}

Un dernier point mais important, à cause de cela, j'avais une valeur logoutId nulle côté Identity Server. Pour lancer le processus de déconnexion, vous devez d'abord appeler SignOut("Cookies", "oidc") côté client mvc. Exemple de point de terminaison dans mon HomeController:

public IActionResult Logout()
{
    return SignOut("Cookies", "oidc");
}

Bonne chance!

0
tscissors