Nicht speziell für Instagram, aber ich habe benutzerdefinierte OAuth Validierung funktioniert für Twitch mit einem ähnlichen Setup wie oben.
Ich bekam die gleichen Null-Fehler von GetExternalLoginInfoAsync und es gab eine Reihe von Schritten, die ich durchlaufen musste, um es zum Laufen zu bringen.
Am Ende habe ich das Problem an der Quellcode für die GetExternalLoginInfoAsync Methode der Suche gefunden hier - Microsoft.AspNetCore.Identity.SignInManager.cs
Das erste, was ich ist buchstäblich in der ersten Zeile des Verfahrens
var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme);
gefunden Die Methode ist so eingestellt, dass immer die Konstante ExternalScheme verwendet wird. Wenn Sie in Ihrem Startup.cs ein benutzerdefiniertes SignInScheme festlegen, wird es beim Aufruf dieser Methode nicht verwendet. SignInScheme als Standardwert zu belassen, schien auch nicht für mich zu funktionieren.
Der LoginProviderKey war null.
if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;}
und nach dem obigen Befestigungs I gefunden, dass keine Ansprüche so eingestellt hatte wurden ich, dass auch manuell einzurichten. Ich fand ein Beispiel dafür auf eine andere Frage Stackoverflow - AddOAuth linkedin dotnet core 2.0
Bitte siehe unten meine letzte Code:
Startup.cs Konfigurieren von OAuth Middleware
Im Startup ich die SignInScheme auf Verwenden Sie den Wert "IdentityConstants.ExternalScheme" und fügen Sie das Ereignis "Customer Claims Setup" in OnCreatingTicket hinzu.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOAuth("Twitch", "Twitch", o =>
{
o.SignInScheme = IdentityConstants.ExternalScheme;
o.ClientId = "MY CLIENT ID";
o.ClientSecret = "MY CLIENT SECRET";
o.CallbackPath = "/signin-twitch";
o.ClaimsIssuer = "Twitch";
o.AuthorizationEndpoint = "https://api.twitch.tv/kraken/oauth2/authorize";
o.TokenEndpoint = "https://api.twitch.tv/api/oauth2/token";
o.UserInformationEndpoint = "https://api.twitch.tv/helix/users";
o.Scope.Add("openid");
o.Scope.Add("user:read:email");
o.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
request.Headers.Add("x-li-format", "json");
var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
var data = user.SelectToken("data")[0];
var userId = (string)data["id"];
if (!string.IsNullOrEmpty(userId))
{
context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId, ClaimValueTypes.String, context.Options.ClaimsIssuer));
}
var formattedName = (string)data["display_name"];
if (!string.IsNullOrEmpty(formattedName))
{
context.Identity.AddClaim(new Claim(ClaimTypes.Name, formattedName, ClaimValueTypes.String, context.Options.ClaimsIssuer));
}
var email = (string)data["email"];
if (!string.IsNullOrEmpty(email))
{
context.Identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String,
context.Options.ClaimsIssuer));
}
var pictureUrl = (string)data["profile_image_url"];
if (!string.IsNullOrEmpty(pictureUrl))
{
context.Identity.AddClaim(new Claim("profile-picture", pictureUrl, ClaimValueTypes.String,
context.Options.ClaimsIssuer));
}
}
};
});
AccountController.cs die Herausforderung zu schaffen
Wenn wir die Herausforderung ausgeben müssen wir auch den LoginProvider Wert enthalten.
public IActionResult LoginWithTwich(string returnUrl = null)
{
var authProperties = new AuthenticationProperties
{
RedirectUri = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }),
Items = { new KeyValuePair<string, string>("LoginProvider", "Twitch") }
};
return Challenge(authProperties, "Twitch");
}
AccountController.cs Umgang mit dem Rückruf
Schließlich, wenn wir behandeln den Rückruf der GetExternalLoginInfoAsync Methode nicht mehr null zurückgibt.
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null)
{
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
//to sign the user in if there's a local account associated to the login provider
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
if (!result.Succeeded)
{
return RedirectToAction("ConfirmTwitchLogin", new { ReturnUrl = returnUrl });
}
if (string.IsNullOrEmpty(returnUrl))
{
return Redirect("~/");
}
else
{
return RedirectToLocal(returnUrl);
}
}
Haben Sie das jemals zur Arbeit gebracht? – Jon
@Jon nicht der eingebaute Weg, nein. Musste es mit einem benutzerdefinierten Workflow tun. –
Gut gemacht! Würde es Ihnen etwas ausmachen, als akzeptierte Antwort zu teilen? – Jon