IdentityServer/OWIN: Client not being redirected to Login page after Logout

Viewed 1660

I have a new IdP that implements IdentityServer4 (.NET Core). I am using it to provide SSO/Cookie authentication/authorization to an MVC5 client app. Since the client app is not .NET Core, I use the IdentityServer3 and Microsoft.Owin nugets in order to integrate. There aren't tons of examples of mixing .NET Core and .NET together like this, but there are a few and I've done my best to make it work. Here is the configuration source code for each:

IdentityServer4 (.NET Core, based largely on this example):

new Client()
{
    ClientId = "myClientId",
    ClientName = "My Client",
    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    Enabled = true,
    RedirectUris = { "http://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
    }
}

My Client (MVC5):

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "http://localhost:5000",
    ClientId = "myClientId",
    RedirectUri = "http://localhost:5002/signin-oidc",
    PostLogoutRedirectUri = "http://localhost:5002/signout-callback-oidc",
    ResponseType = "code id_token",
    SignInAsAuthenticationType = "Cookies",
    Scope = "openid",
    Notifications = new OpenIdConnectAuthenticationNotifications()
    {
        AuthorizationCodeReceived = n => {
            n.OwinContext.Response.Cookies.Append("stored_id_token", n.ProtocolMessage.IdToken);
            return Task.FromResult(0);
        },
        RedirectToIdentityProvider = n => {
            if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.LogoutRequest)
            {
                var idTokenHint = n.Request.Cookies["stored_id_token"];
                if (idTokenHint != null)
                {
                    n.ProtocolMessage.IdTokenHint = idTokenHint;
                    var signOutMessageId = n.OwinContext.Environment.GetSignOutMessageId();  // returns NULL!
                    //var signOutMessageId = n.OwinContext.Request.Query.Get("id");  // same thing as line above
                    if (signOutMessageId != null)
                    {
                        n.ProtocolMessage.State = signOutMessageId;
                    }
                }
            }
            return Task.FromResult(0);
        }
    }
});

Logout mostly works ok. The issue I have is with redirecting back to the login page so that the enduser can login again to the client they just logged out of via the link highlighted here: The link highlighted here
The RedirectUri is configured correctly on both sides of configuration (IdP and Client), and the hyperlink's href value is set in the View (pictured), but that URL also needs a query param called "state" attached to it so that it knows which application to log back into (eg. http://localhost:5002/signout-callback-oidc?state=123456789 Clicking this link without the "state" param gives you a 404.). The issue I'm having is that I'm unable to get/set this "state" value in "My Client".

From everything I've read, you get it by calling n.OwinContext.Environment.GetSignOutMessageId() which is actually just calling n.OwinContext.Request.Query.Get("id") under the covers, but it always returns null. Any idea why this returns null?? Thank you!

0 Answers
Related