У меня есть новый IdP, который реализует IdentityServer4 (.NET Core). Я использую его для обеспечения аутентификации / авторизации SSO / Cookie для клиентского приложения MVC5. Поскольку клиентское приложение не является .NET Core, я использую нативы IdentityServer3 и Microsoft.Owin для интеграции. Не существует тонны примеров смешения .NET Core и .NET вместе, как это, но есть несколько, и я приложил все усилия, чтобы это работало. Вот исходный код конфигурации для каждого:
IdentityServer4 (ядро .NET, основанное главным образом на этом примере ):
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,
}
}
Мой клиент (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);
}
}
});
Выход в основном работает нормально. У меня проблема с перенаправлением обратно на страницу входа, чтобы конечный пользователь мог снова войти в систему на клиенте, с которым он только что вышел, по ссылке, выделенной здесь:
RedirectUri настроен правильно на обеих сторонах конфигурации (IdP и клиент), а значение href гиперссылки задается в представлении (на рисунке), но этому URL-адресу также необходим параметр запроса, называемый «состоянием», чтобы он знал, какой приложение для входа в систему (например, http://localhost:5002/signout-callback-oidc?state=123456789 Если щелкнуть эту ссылку без параметра «state», вы получите 404.). У меня проблема в том, что я не могу получить / установить это значение "состояния" в "Мой клиент".
Из всего, что я прочитал, вы получаете это, вызывая n.OwinContext.Environment.GetSignOutMessageId()
, который на самом деле просто вызывает n.OwinContext.Request.Query.Get("id")
под прикрытием, но он всегда возвращает ноль. Любая идея, почему это возвращает нуль ??
Спасибо!