Posts about ASP.NET
Hello, I have an ASP.NET Core API with Identity and EF and SQL Server acting as IdentityStore. I also have Facebook authentication middleware set up like this:
services.AddAuthentication(o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddFacebook(fb =>
{
fb.AppId = Configuration["FacebookAppId"];
fb.AppSecret = Configuration["FacebookAppSecret"];
fb.SaveTokens = true;
});
I implemented the Auth controller following this sample code from Microsoft.
[HttpGet("{scheme}")]
public async Task Get([FromRoute] string scheme)
{
var auth = await Request.HttpContext.AuthenticateAsync(scheme);
bool isNotAuthenticated = !auth.Succeeded
|| auth?.Principal == null
|| !auth.Principal.Identities.Any(id => id.IsAuthenticated)
|| string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token"));
if (!isNotAuthenticated)
{
// Not authenticated, challenge
await Request.HttpContext.ChallengeAsync(scheme);
}
else
{
var claims = auth.Principal.Identities.FirstOrDefault()?.Claims;
var email = string.Empty;
email = claims?.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value;
// Get parameters to send back to the callback
var qs = new Dictionary<string, string>
{
{ "access_token", auth.Properties.GetTokenValue("access_token") },
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
{ "expires_in", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() },
{ "email", email }
};
// Build the result url
var url = callbackScheme + "://#" + string.Join(
"&",
qs.Where(kvp => !string.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1")
.Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}"));
// Redirect to final url
Request.HttpContext.Response.Redirect(url);
}
}
If the user is not authenticated, the bool value "isNotAuthenticated" is true, meaning the controller challenges the user to complete the auth workflow with the given provider (in my case Facebook). If the challenge is completed successfully, the auth provider calls this same controller (as I've set it to be the callback URL) and this time the "isNotAuthenticated" value is "true", meaning we've successfully logged in the user via an external provider. This code works.
However what I cannot understand is how to "insert" this user's external identity into my IdentityStore (in the Identity database) so I can store the user info for other purposes.
Basically I guess the part that I'm missing is - how do I integrate the identity received by the external login as an IdentityUser in my app? Sorry if the question is not worded correctly - if something is unclear I will be happy to clarify in the comments.
Thanks