Как добиться единого выхода между двумя веб-приложениями MVC (оба являются гибридными клиентами) с использованием сервера идентификации 3? - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть 2 приложения ASP.NET MVC, которые используют промежуточное программное обеспечение OpenID UseOpenIdConnectAuthentication для единого входа в оба.Единый вход в систему работает правильно.Если я вхожу в приложение 1, а затем проверяю, вошел ли я и в приложение 2, которое подключается к серверу идентификации, я вижу себя вошедшим в систему.

Конфигурации в Startup.cs для обоих приложений одинаковы икак описано ниже:

        public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });


        AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub";
        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

        app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = ClientId,
            //hybridclient1
            Authority = IdServBaseUri,
            RedirectUri = ClientUri,
            PostLogoutRedirectUri = ClientUri,
            ResponseType = "code id_token token",
            Scope = "openid profile email roles sampleApi offline_access",
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "role"
            },
            SignInAsAuthenticationType = "Cookies",
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n => {
                    var userInfoClient = new UserInfoClient(UserInfoEndpoint);
                    var userInfoResponse = await userInfoClient.GetAsync(n.ProtocolMessage.AccessToken);

                    var identity = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                    identity.AddClaims(userInfoResponse.Claims);
                    //hybridclient1
                    var tokenClient = new TokenClient(TokenEndpoint, ClientId, SecretKey);
                    var response = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);

                    identity.AddClaim(new Claim("access_token", response.AccessToken));
                    identity.AddClaim(new Claim("expires_at", DateTime.UtcNow.AddSeconds(response.ExpiresIn).ToLocalTime().ToString(CultureInfo.InvariantCulture)));
                    identity.AddClaim(new Claim("refresh_token", response.RefreshToken));
                    identity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                    identity.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));

                    n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);

                },
                RedirectToIdentityProvider = n =>
                {
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    {
                        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token").Value;
                        n.ProtocolMessage.IdTokenHint = idTokenHint;
                    }

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




    }

Конфигурации клиентов на сервере идентификации, как указано ниже:

            new Client {

            ClientId = "hybridclient",
            ClientName = "Example Hybrid Client",
            ClientSecrets = new List<Secret> {
                new Secret("idsrv3test".Sha256())
            },
            Enabled = true,
            Flow = Flows.Hybrid,
            RequireConsent = false,
            RedirectUris = new List<string> {
                hybridAppUrl,hybridApp1Url
            },
            PostLogoutRedirectUris = new List<string> {
                 hybridAppUrl,hybridApp1Url
            },
            LogoutUri= hybridAppUrl+"Account/SignoutCleanup",
            AllowedScopes = new List<string> {
                Constants.StandardScopes.OpenId,
                Constants.StandardScopes.Profile,
                Constants.StandardScopes.Email,
                Constants.StandardScopes.Roles,
                Constants.StandardScopes.OfflineAccess,
                 "sampleApi",
                 //"id"
            },
            AccessTokenType = AccessTokenType.Jwt,
            RefreshTokenUsage=TokenUsage.ReUse,
            RefreshTokenExpiration=TokenExpiration.Sliding
        }

Выход выполняется с использованием следующего кода:

   public ActionResult SignOut()
    {
        Request.GetOwinContext().Authentication.SignOut();
        return this.Redirect("/");
    }

    [AllowAnonymous]
    public void SignoutCleanup(string sid)
    {
        var cp = (ClaimsPrincipal)User;
        var sidClaim = cp.FindFirst("sid");
        if (sidClaim != null && sidClaim.Value == sid)
        {
            Request.GetOwinContext().Authentication.SignOut("Cookies");
        }
    }

КогдаЯ пытаюсь выйти из приложения app1, оно также выходит из приложения app2 на локальном хосте с помощью IIS express.Но я разместил и приложения, и сервер идентификации отдельно на IIS 8.5 и пытаюсь добиться того же, но когда я вышел из приложения app1, я не выходил из приложения app2.Он остается в системе.

Я также просмотрел статью о единственном выходе @brockallen и другие подобные вопросы о github и stackoverflow для identityserver3, но я не получил ответа на него.Могу ли я добиться этого, установив разные файлы cookie для разных доменов или любым другим способом?

Как мне добиться единого выхода для разных доменов с использованием сервера идентификации 3?

...