I have a DunendeSoftware Identity Server (v5.0.0-preview2.13) running under ASPNetCore 5.0 and using HttpSys as the web server (no Kestrel or IIS). I have a second website (call it protectedsite) using implicit flow to authenicate to the Identity Server. It is also ASPNetCore 5.0 hosted in HttpSys. I can Login and make authenticated calls on my protectedsite. I can logout by calling a the following code in the protectedsite
[AllowAnonymous]
public IActionResult Logout ()
{
return SignOut(new AuthenticationProperties
{
RedirectUri = "/home/loggedout"
}, "Cookies", "oidc");
}
The problem comes in the call back to home/loggedout. The code in OpenIdConnectHandler.HandleSignOutCallbackAsync receives control anytime a request is made to home/Loggedout and the actual action is never invoked. The intercept is done after the Signout code in IDS completes AND even if I do https://ProtectedSite/Home/LoggedOut without even touching IDS.
It appears that OpenIdConnectHandler.HandleSignOutCallbackAsync will intercept any url that looks like OpenIdConnectOptions.SignedOutCallbackPath. If I remove SignedOutCallbackPath setting in my startup, then the request is not intercepted and the action runs, BUT then IDS declares my PostLogoutRedirectUri to be invalid because the default of https://protectedsite/signout-callback-oidc is not in the list of valid post logout urls.
At this point my bottom line problem is that I can either have a redirect from IDS to my protected site that does not really work (leaves a blank page on the screen) or I can forego the redirect to protectedsite and the standard Duende logout message is displayed while still on the Duende IDS site. I do not want the user left on the Duende site.
OIDC setup in protectedsite
AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://IDS:443";
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.GetClaimsFromUserInfoEndpoint = true;
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("api1");
options.Scope.Add("offline_access");
options.Scope.Add("profile");
options.SignInScheme = "Cookies";
options.SignedOutCallbackPath =
Microsoft.AspNetCore.Http.PathString.FromUriComponent("/home/loggedout");
// options.SignedOutRedirectUri = "https://protectedsite/home/loggedout";
});
This has been a journey due to bad/missing documentation and bad examples. Note that the (code supplied by @tore above) shows no return from the Logout action. That appears to be a very important part of the solution. Also just after the response to this question was made, I stumbled on a post at Bug Report about RedirectUri not working which describes the path of a logout redirect through ASPNetIdentity. It cannot be summarized here, but as long as the link is available, it should be consulted. Had I found it two days earlier it would have saved me a day and half of stepping through code.
My problems were many.
Lesson Learned do not return a result from the logout action.
Notice the change below to Startup in the protected site
AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://IDS:443";
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.GetClaimsFromUserInfoEndpoint = true;
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("api1");
options.Scope.Add("offline_access");
options.Scope.Add("profile");
options.SignInScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
// options.SignedOutCallbackPath = Microsoft.AspNetCore.Http.PathString.FromUriComponent("/home/loggedout");
options.SignedOutRedirectUri = "/home/loggedout";
});
Lesson learned is the SignedOutCallbackPath is the uri that will be called on the protected site after the callback. It defaults to /signout-callback-oidc and, as far as I can tell, should be left as the default, just ensure that you set the PostLogoutRedirectUris of the IDS Client configuration to the same value.
Finally, I offer this note. I do not know if a RedirectUri can be supplied in the logout action and made to work as a runtime decision. I currently am of the opinion that it can be IF and ONLY IF, the URI there is also set in the PostLogoutRedirectUris of the IDS client configuration. I also believe, but do not know, that if the redirected to site honors the SignedOutRedirectUri, it would be followed on the site picked by the RedirectUri, but I have not attempted to prove either of these theories.