I have a working application using OpenIdDict back end with support for internal registration, Login with Google, and Login with Apple.
From a web page, everything works beautifully, however, in my mobile application, Apple has demanded that I use their "Login with Apple" flow.
I have part of that working already. i.e. I can authenticate with apple which returns an authorization_code, id_token (JWT token which contains, among other things, the email address) which is apparently good for 5 minutes, and the apple id_token.
Now, what I need is an endpoint on my server which can authenticate that auth_code / id_token from Apple and return my own OpenIdDict authentication code or auth token.
I figured since I already have Login with Apple working on my web page, this should be easy but to be honest, I get confused with authentication all the time.
Here's my Web Server code:
options.UseWebProviders()
.AddApple(options =>
{
options.SetClientId(extAuth.Apple.ClientId)
.SetTeamId(extAuth.Apple.TeamId)
.SetSigningKey(temp)
.SetRedirectUri(extAuth.Apple.CallbackUri);
})
.AddGoogle(options =>
{
options.SetClientId(extAuth.Google.ClientId)
.SetClientSecret(extAuth.Google.ClientSecret)
.SetRedirectUri(extAuth.Google.CallbackUri);
});
Ideally, I would like something like this:
[HttpPost("~/connect/token/apple"), IgnoreAntiferyToken, Produces("application/json")]
public async Task<IActionResult> ExchangeMobile()
{
var provider = "apple";
var redirectUrl = ""; // why would I need this?
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
properties.Parameters.Add("scope", "name email");
properties.Parameters.Add("response_mode", "form_post");
// var info = await _signInManager.GetExternalLoginInfoAsync();
string id_token = "xxxxxx"; // from post body
string email = "[email protected]"; // from post body or id_token
string user_id = "[Apple User Id]"; // from post body or id_token
JwtSecurityToken token = new JwtSecurityToken(id_token);
email = token.Payload.ContainsKey("email") ? token.Payload["email"].ToString() : email;
user_id = token.Payload.ContainsKey("user_id") ? token.Payload["user_id"].ToString() : user_id;
// Get Auth_code, ID_Token, and UserId from Post Body
var user = await _userManager.FindByLoginAsync(provider, id_token);
if (user == null)
{
// Create User using provider / id_token
user = Activator.CreateInstance<ApplicationUser>();
user.CreatedOn = DateTime.UtcNow;
user.ChangedOn = user.CreatedOn;
user.EmailConfirmed = true;
await _userStore.SetUserNameAsync(user, email, CancellationToken.None);
await _emailStore.SetEmailAsync(user, email, CancellationToken.None);
await _userManager.CreateAsync(user);
var info = await _signInManager.GetExternalLoginInfoAsync();
await _userManager.AddLoginAsync(user, info);
// etc...
}
// authenticate user with apple
var result = await _signInManager.ExternalLoginSignInAsync(provider, user_id, isPersistent: false, bypassTwoFactor: true);
// get auth token from my identity server
// no clue what I am doing here.
return Ok("{json with auth token, refresh token, etc. }");
}
but although I feel like I have all the necessary pieces, I cannot fathom how to put them together.
All help is much appreciated.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744304731a4567672.html
评论列表(0条)