【发布时间】:2022-02-07 14:21:25
【问题描述】:
我正在尝试在 IdentityServer4 中实现外部 oauth 身份验证。 所有身份验证请求都成功。我在应用程序日志中有一条消息 AuthenticationScheme: Identity.External signed in.。 但是,当身份验证过程尝试返回到 ExternalLoginCallback 操作时,它会在 HTTP 302 之后出现错误 500(oauth 状态丢失或无效)。 Screenshot is here
- 结果 302。请求 https://localhost:5999/Account/ExternalLoginCallback?state=xxx&code=xxx&session_state=xxx
- 然后请求转到 https://localhost:5999/Account/ExternalLoginCallback(不带任何参数)
我的 IS4 启动
IdentityServerConfiguration.AddIdentityServer(services, _configuration);
services
.AddAuthentication()
.AddTinkoff(_configuration)
.AddSber(_configuration)
.AddEsia(_configuration);
AddTinkoff 扩展方法:
public static AuthenticationBuilder AddTinkoff(this AuthenticationBuilder builder, IConfiguration config)
{
return builder.AddOAuth("TinkoffId", "Tinkoff ID", options =>
{
options.AuthorizationEndpoint = "https://id.tinkoff.ru/auth/authorize?response_type=code";
options.TokenEndpoint = "https://id.tinkoff.ru/auth/token?grant_type=authorization_code";
options.UserInformationEndpoint = "https://id.tinkoff.ru/userinfo/userinfo";
options.CallbackPath = "/Account/ExternalLoginCallback";
options.ClientId = "xxx";
options.ClientSecret = "xxxx";
options.SaveTokens = true;
options.SignInScheme = IdentityConstants.ExternalScheme;
options.BackchannelHttpHandler = new TinkoffAuthorizingHandler(new HttpClientHandler(), options);
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "name");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
options.ClaimActions.MapAll();
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Post, context.Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
request.Headers.Add(
HttpRequestHeader.ContentType.ToString(),
"application/x-www-form-urlencoded"
);
request.Content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("client_id",options.ClientId),
new KeyValuePair<string, string>("client_secret",options.ClientSecret)
});
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user.RootElement);
},
//OnTicketReceived = async context =>
//{
// context.HttpContext.User = context.Principal;
// //context.SkipHandler();
//}
};
//options.Scope.Add("profile");
//options.Scope.Add("email");
//options.Scope.Add("phone");
});
}
我的 ExternalLogin 操作:
[HttpPost]
[HttpGet]
[AllowAnonymous]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
_logger.LogInformation($"External login fired. ReturnUrl='{returnUrl}'. Provider='{provider}'");
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
在调试时未触发 ExternalLoginCallback 操作。
我做错了什么。为什么请求在没有参数的情况下重定向到自身?
谢谢。
【问题讨论】:
标签: oauth identityserver4 .net-5