Why IdentityServer4 provide/send-back different cookie for each clients?

久未见 提交于 2020-05-17 06:26:10

问题


I have two mvc client application mvc_client1 and mvc_client2. When I logged into mvc_client1 and click the menu to launch mvc_client2 automatically authenticate and open authorized page as per IdentityServer4 documentation.

But, if I trigger logout from any of the client only logout the client which I requested the logout. I have already read documentation and implemented Back-Channel-Logout. Even though single sign-out not working as documented.

I noticed something that, Identity server provide/send-back different cookie value for each client when authorize. Will it causes an single sign-out? (Please refer attached image) If yes, how to resolve this?

Or, Is this because of recent SameSite update in all modern browsers?

Client1:

Client2:

EDIT :

IdentityServer Project's Startup:

public void ConfigureServices(IServiceCollection services)
{
    //...

    //...
    services.AddIdentityServer()
        .AddInMemoryIdentityResources(IdentityConfiguration.GetIdentityResources())
        .AddInMemoryClients(IdentityConfiguration.GetClients())
        .AddDeveloperSigningCredential()
        .AddProfileService<CustomProfileService>()
        .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();
}

Client Project's Startup:

public void Configuration(IAppBuilder app)
{
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = "Cookies",
        CookieSecure = CookieSecureOption.SameAsRequest,
        CookieHttpOnly = true,
        ExpireTimeSpan = TimeSpan.FromMinutes(180),
    });

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        Authority = "https://localhost:44306/",

        ClientId = "mvc_client1",
        ClientSecret = "secret",
        Scope = "openid profile",
        ResponseType = "code id_token",
        RedirectUri = "https://localhost:44307/",

        SignInAsAuthenticationType = "Cookies",
        UseTokenLifetime = false,
        RequireHttpsMetadata = true,

        Notifications = new OpenIdConnectAuthenticationNotifications
        {
            SecurityTokenValidated = n =>
            {
                var id = n.AuthenticationTicket.Identity;
                id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                n.AuthenticationTicket = new AuthenticationTicket(
                       id,
                       n.AuthenticationTicket.Properties);
                return Task.FromResult(0);
            },

            RedirectToIdentityProvider = n =>
            {
                if (IsAjaxRequest(n.Request))
                {
                    n.Response.StatusCode = 401;
                    n.Response.Headers.Remove("Set-Cookie");
                    n.State = NotificationResultState.HandledResponse;
                }

                switch (n.ProtocolMessage.RequestType)
                {
                    case Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Authentication:
                        {
                            n.OwinContext.Authentication.SignOut("Cookies");
                            break;
                        }
                    case Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout:
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                                n.ProtocolMessage.ClientId = ConfigurationManager.AppSettings["ClientID"];
                            }
                            break;
                        }
                }

                return Task.FromResult(0);
            }
        }
    });
}

private bool IsAjaxRequest(IOwinRequest request)
{
    IReadableStringCollection query = request.Query;
    if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
    {
        return true;
    }
    IHeaderDictionary headers = request.Headers;
    return (headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest");
}

My Client Configuration:

public static IEnumerable<IdentityResource> GetIdentityResources() =>
new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
};

public static IEnumerable<Client> GetClients() =>
new List<Client> {
    new Client {
        ClientName = "MVC Client 1",
        ClientId = "mvc_client1",
        AllowedGrantTypes = GrantTypes.Hybrid,
        ClientSecrets =
        {
            new Secret("secret".Sha256())
        },
        RedirectUris = new List<string>
        {
            "https://localhost:44307/"
        },
        PostLogoutRedirectUris = new List<string>
        {
            "https://localhost:44307/"
        },
        AllowedScopes =
        {
            IdentityServerConstants.StandardScopes.OpenId,
            IdentityServerConstants.StandardScopes.Profile
        },
        AlwaysIncludeUserClaimsInIdToken = true,
        RequireConsent = false,
        BackChannelLogoutSessionRequired = true,
        BackChannelLogoutUri = "https://localhost:44307/Home/SignoutOidc",
        Properties = new Dictionary<string, string>()
        {
            {"ForgetPasswordUri", "https://localhost:44307/account/forgotpassword" },
            {"SubscribeUri", ""https://localhost:44307/account/register" }
        }
    }
};

来源:https://stackoverflow.com/questions/61400654/why-identityserver4-provide-send-back-different-cookie-for-each-clients

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!