Pas spécifiquement pour Instagram mais j'ai une validation OAuth personnalisée qui fonctionne pour Twitch en utilisant une configuration similaire à celle ci-dessus. Je recevais les mêmes erreurs Null de GetExternalLoginInfoAsync et il y avait un certain nombre d'étapes que je devais passer pour le faire fonctionner.
En fin de compte, j'ai trouvé le problème en regardant le code source pour la méthode GetExternalLoginInfoAsync trouve ici - Microsoft.AspNetCore.Identity.SignInManager.cs
La première chose que je trouve est littéralement sur la première ligne de la méthode
var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme);
La méthode est configurée pour utiliser toujours la constante ExternalScheme donc si vous définissez un SignInScheme personnalisé dans votre Startup.cs il ne sera pas utilisé lors de l'appel de cette méthode. Laisser le paramètre SignInScheme défini comme valeur par défaut ne semblait pas fonctionner pour moi.
La LoginProviderKey était null.
if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;}
Et après la fixation qui précède, je trouve que aucune réclamation étaient mis si je devais mettre en place que manuellement. J'ai trouvé un exemple sur une autre question Stackoverflow - AddOAuth linkedin dotnet core 2.0
S'il vous plaît voir ci-dessous mon code final:
Startup.cs Configuration OAuth Middleware
Dans le démarrage, je mis le SignInScheme à utilisez la valeur IdentityConstants.ExternalScheme et ajoutez l'événement de configuration Claims du client dans OnCreatingTicket.
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 créant le Défi
Quand nous émettons le défi que nous devons également inclure la valeur LoginProvider.
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 Manipulation du Callback
Enfin, lorsque nous traitons le rappel de la méthode GetExternalLoginInfoAsync ne retourne plus nulle.
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);
}
}
Avez-vous déjà obtenu cela au travail? – Jon
@Jon pas la manière intégrée, non. A dû le faire avec un flux de travail personnalisé. –
Bravo! Cela vous dérangerait-il de partager comme réponse acceptée? – Jon