on my api server I use Xamarin.Essentials: Web Authenticator to login via social account (google, fb, apple). It works fine for google and facebook logins, but not apple. Nginx when logging in via google returns something like this:
- [15/Mar/2022:07:10:57 +0000] "GET /api/mobileauth/Google HTTP/2.0" 302 0 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1"
- [15/Mar/2022:07:10:58 +0000] "GET /signin-google?state=CfD..(e.t.c)
I can handle it, and it works fine, but when I try to log in, apple returns error 500 like this:
- [15/Mar/2022:07:14:11 +0000] "GET /api/mobileauth/Apple HTTP/2.0" 302 0 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1"
- [15/Mar/2022:07:14:34 +0000] "POST /signin-apple HTTP/2.0" 500 0 "https://appleid.apple.com/" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1"
Maybe someone had a similar problem and knows why is this happening? The server goes through cloudflare which has full ssl. Anyone have any ideas? my startup:
services.AddAuthentication(o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddFacebook(fb =>
{
fb.AppId = "my AppId";
fb.AppSecret = "my AppSecret ";
fb.SaveTokens = true;
})
.AddGoogle(g =>
{
g.ClientId = "my ClientId ";
g.ClientSecret = "my ClientSecret ";
g.SaveTokens = true;
})
.AddApple(a =>
{
a.ClientId = "my ClientId";
a.KeyId = "my KeyId ";
a.TeamId = "my TeamId ";
a.UsePrivateKey(keyId
=> WebHostEnvironment.ContentRootFileProvider.GetFileInfo($"AuthKey_my_KeyId.p8"));
a.SaveTokens = true;
});
my controller:
[HttpGet("{scheme}")]
public async Task Get([FromRoute] string scheme)
{
try
{
var auth = await Request.HttpContext.AuthenticateAsync(scheme);
if (!auth.Succeeded
|| auth?.Principal == null
|| !auth.Principal.Identities.Any(id => id.IsAuthenticated)
|| string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")))
{
// 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", (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);
}
}
catch(Exception ex)
{
_logger.Error("Exception!" + ex + " Model:" + scheme);
}
}