#c# #openiddict
Вопрос:
Я довольно новичок в OpenIddict, и я изо всех сил пытаюсь получить соответствующий принципал в функции выхода из системы authorizationController, когда функция вызывается из Postman. Вход в систему отлично работает от почтальона, и вход выход из MVC-клиента также работает нормально.
Я не понимаю, почему IDTokenHint, установленный клиентом MVC, сопоставляется OpenIddict с правильным участником, но IdTokenHint, установленный в обработчике ValidateLogoutRequestContext, — нет. Кто-нибудь может мне помочь, пожалуйста?
Вот что я пытался:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddOpenIddict()
.AddServer(options =>
{
options.RegisterScopes(OpenIddictConstants.Scopes.OpenId,
OpenIddictConstants.Scopes.Profile);
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
options.AllowClientCredentialsFlow().AllowAuthorizationCodeFlow().AllowHybridFlow();
options.SetAuthorizationEndpointUris("/connect/authorize")
.SetTokenEndpointUris("/connect/token").SetLogoutEndpointUris("/connect/logout");
options
.AddEphemeralEncryptionKey()
.AddEphemeralSigningKey()
.DisableAccessTokenEncryption();
options.EnableDegradedMode();
options.UseAspNetCore().EnableTokenEndpointPassthrough().
EnableAuthorizationEndpointPassthrough().EnableLogoutEndpointPassthrough();
options.AddEventHandler<OpenIddict.Server.OpenIddictServerEvents.ValidateLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
var x = context.PostLogoutRedirectUri;
var authHeader = context.Transaction.GetHttpRequest()?.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
var auth = System.Net.Http.Headers.AuthenticationHeaderValue.Parse(authHeader);
if (auth.Scheme == "Bearer")
{
context.Request.IdTokenHint = auth.Parameter;
}
}
return defau<
}));
authorizationController.cs
[HttpGet("~/connect/logout")]
[HttpPost("~/connect/logout")]
public async Task LogoutAsync()
{
var request = HttpContext.GetOpenIddictServerRequest();
var clientId = request.ClientId;
var principal = (await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme))?.Principal;
if (principal != null) {
var name = principal.Identity.Name;
if (string.IsNullOrEmpty(name) amp;amp; principal.HasClaim(System.Security.Claims.ClaimTypes.Name))
name = principal.GetClaim(System.Security.Claims.ClaimTypes.Name);
if (string.IsNullOrEmpty(name) amp;amp; principal.HasClaim(OpenIddictConstants.Claims.Subject))
name = principal.GetClaim(OpenIddictConstants.Claims.Subject);
var claims = new List<Claim>
{
new Claim(System.Security.Claims.ClaimTypes.Name, name),
};
if (principal.HasClaim(System.Security.Claims.ClaimTypes.Sid)) claims.Add(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Sid, principal.GetClaim(System.Security.Claims.ClaimTypes.Sid)));
if (principal.HasClaim(System.Security.Claims.ClaimTypes.Email)) claims.Add(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Email, principal.GetClaim(System.Security.Claims.ClaimTypes.Email)));
if (principal.HasClaim(OpenIddictConstants.Claims.AuthorizedParty)) clientId = principal.GetClaim(OpenIddictConstants.Claims.AuthorizedParty);
var claimsIdentity = new System.Security.Claims.ClaimsIdentity(claims, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme);
var claimsPrincipal = new System.Security.Claims.ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(claimsPrincipal);
//perform some custom logout tasks
await Helpers.Func.LogoutAsync(claimsPrincipal, settings, HttpContext, clientId);
}
await HttpContext.SignOutAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
}
И это то, что делает MVC-клиент, где работает выход из системы:
AccountController.cs (MVC-Клиент)
[HttpGet(), HttpPost()]
[Route("/logout")]
public async Task<IActionResult> LogOut()
{
await HttpContext.SignOutAsync(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectDefaults.AuthenticationScheme);
return SignOut(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme);
}
Startup.cs (MVC-Клиент, IdTokenHint устанавливается с помощью контекста.Протокольное сообщение)
services.AddAuthentication(options =>
{
options.DefaultScheme = "smart";
})
.AddPolicyScheme("smart", "Bearer or Cookie", options =>
{
options.ForwardDefaultSelector = context =>
{
var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith("Bearer ") ?? false;
if (bearerAuth)
return Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
else
return Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
};
})
.AddCookie(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/login";
options.AccessDeniedPath = "/login";
options.LogoutPath = "/logout";
options.ExpireTimeSpan = TimeSpan.FromMinutes(50);
options.SlidingExpiration = false;
})
.AddOpenIdConnect(options =>
{
options.ClientId = "xyapi";
options.SignInScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
options.RequireHttpsMetadata = false;
options.GetClaimsFromUserInfoEndpoint = false;
options.SaveTokens = true;
// Use the authorization code flow.
options.ResponseType = Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectResponseType.CodeIdTokenToken;
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
// Note: setting the Authority allows the OIDC client middleware to automatically
// retrieve the identity provider's configuration and spare you from setting
// the different endpoints URIs or the token validation parameters explicitly.
options.Authority = "https://localhost:44362/";
options.SignedOutRedirectUri = "/signedout";
//options.SignedOutCallbackPath = "/signout-oidc";
options.CallbackPath = "/signin-oidc";
options.Scope.Add("openid");
options.Scope.Add("profile");
//options.Scope.Add("roles");
options.SecurityTokenValidator = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler
{
// Disable the built-in JWT claims mapping feature.
InboundClaimTypeMap = new Dictionary<string, string>()
};
options.ClaimActions.MapJsonKey(System.Security.Claims.ClaimTypes.Sid, "sid");
options.TokenValidationParameters.NameClaimType = System.Security.Claims.ClaimTypes.Name;
options.TokenValidationParameters.RoleClaimType = "role";
var events = new OpenIdConnectEvents
{
OnRedirectToIdentityProviderForSignOut = context =>
{
var idToken = context.HttpContext.User.FindFirst("id_token");
if (idToken != null)
{
context.ProtocolMessage.IdTokenHint = idToken.Value;
} else
{
var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith("Bearer ") ?? false;
if (bearerAuth)
{
context.ProtocolMessage.IdTokenHint = context.Request.Headers["Authorization"].FirstOrDefault().Substring(7);
}
}
return Task.CompletedTask;
}
};
options.Events = events;
})
Комментарии:
1. Пожалуйста, проясните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы точно указать, что вам нужно. Поскольку это написано в настоящее время, трудно точно сказать, о чем вы просите.