几个月前开始的与Facebook身份验证有关的问题,错误为:"Error from RemoteAuthentication: An error occurred when retrieving Facebook user information (Forbidden). Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled.."
。有时很难复制,并且在第2次或第3次按钮提交单击后,外部登录可能会起作用。
这是我启动时的代码:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.AccessDeniedPath = new PathString("/Account/AccessDenied");
options.ExpireTimeSpan = TimeSpan.FromDays(10);
options.Cookie.SameSite = SameSiteMode.None;
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.Value.StartsWith("/api"))
{
context.Response.Clear();
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
context.Response.Redirect(context.RedirectUri);
return Task.FromResult(0);
};
})
.AddFacebook(options =>
{
options.AppId = Configuration["Facebook:AppKey"];
options.AppSecret = Configuration["Facebook:AppSecret"];
options.Events.OnRemoteFailure = (context) =>
{
context.Response.Redirect("/account/login");
context.HandleResponse();
return Task.CompletedTask;
};
})
.AddGoogle(options =>
{
options.ClientId = Configuration["Google:AppKey"];
options.ClientSecret = Configuration["Google:AppSecret"];
options.Events.OnRemoteFailure = (context) =>
{
context.Response.Redirect("/account/login");
context.HandleResponse();
return Task.CompletedTask;
};
});
并且来自控制器:
[HttpGet("/account/login")]
[AllowAnonymous]
public async Task<IActionResult> Login(string error = "", string returnUrl = "", string errorStateKey = null, string errorStateMessage = null)
{
if (!string.IsNullOrEmpty(returnUrl))
{
Request.QueryString.Add("ReturnUrl", returnUrl);
}
if (HttpContext.User.Identity.IsAuthenticated)
{
if (string.IsNullOrEmpty(returnUrl)) return RedirectToAction("Index", "Home");
// Check if ReturnUrl is Wp Support Site Url>>
var isAbsoluteReturnUrl = IsAbsoluteValidUrl(returnUrl);
if (!isAbsoluteReturnUrl) return RedirectToAction("Index", "Home");
var uriWpReturn = new Uri(returnUrl);
var hostWpReturn = uriWpReturn.Host;
var uriWp = new Uri(_wpOptions.Value.Host);
var hostWp = uriWp.Host;
if (hostWpReturn == hostWp)
{
returnUrl = string.Format(_wpOptions.Value.AutologinUrl, CurrentSalesPeople.Var1, returnUrl);
return Redirect(returnUrl);
}
// << check if ReturnUrl is Wp Support Site
return RedirectToAction("Index", "Home");
}
if (!string.IsNullOrEmpty(error))
{
ViewData["Error"] = error;
}
if (errorStateKey != null && errorStateMessage != null)
{
ModelState.AddModelError(errorStateKey, errorStateMessage);
}
return await ShowLoginViewAsync(null);
}
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginModel model)
{
if (!ModelState.IsValid) return await ShowLoginViewAsync(model);
var validatePeople = await _authService.ValidateSalespeople(model.Login, model.Password);
if (!validatePeople.Success)
{
var errorStateKey = "Password";
var errorStateMessage = validatePeople.Message;
if (!string.IsNullOrEmpty(model.ReturnUrl))
{
return RedirectToAction("Login", new { returnUrl = model.ReturnUrl, errorStateKey = errorStateKey, errorStateMessage = errorStateMessage });
}
ModelState.AddModelError(errorStateKey, errorStateMessage);
return await ShowLoginViewAsync(model);
}
var salespeopleRole = await _roleService.GetRoleNameBySalespeopleId(validatePeople.Model.SId);
if (!salespeopleRole.Success)
{
var errorStateKey = "";
var errorStateMessage = validatePeople.Message;
if (!string.IsNullOrEmpty(model.ReturnUrl))
{
return RedirectToAction("Login", new { returnUrl = model.ReturnUrl, errorStateKey = errorStateKey, errorStateMessage = errorStateMessage });
}
ModelState.AddModelError(errorStateKey, errorStateMessage);
return await ShowLoginViewAsync(model);
}
var requestForDealerToolkit = await _dealerService.GetToolkitTypeBySalespeopleIddAsync(validatePeople.Model.SId);
if (!requestForDealerToolkit.Success)
{
var errorStateKey = "";
var errorStateMessage = "Problem with your toolkit subscription. Please tell a support about this error";
if (!string.IsNullOrEmpty(model.ReturnUrl))
{
return RedirectToAction("Login", new { returnUrl = model.ReturnUrl, errorStateKey = errorStateKey, errorStateMessage = errorStateMessage });
}
ModelState.AddModelError(errorStateKey, errorStateMessage);
return await ShowLoginViewAsync(model);
}
var getToolkit = GetToolkitTypeForSalespeople(validatePeople.Model.SubscriptionTypeId, requestForDealerToolkit.Model);
var roleName = new RoleHelper(getToolkit, salespeopleRole.Model == "Manager").RoleName;
if (roleName == "None")
{
var errorStateKey = "Password";
var errorStateMessage = "You don't have permissions";
if (!string.IsNullOrEmpty(model.ReturnUrl))
{
return RedirectToAction("Login", new { returnUrl = model.ReturnUrl, errorStateKey = errorStateKey, errorStateMessage = errorStateMessage });
}
ModelState.AddModelError(errorStateKey, errorStateMessage);
return await ShowLoginViewAsync(model);
}
//We clear session before each login to prevent caching changes in new app vesrions
//HttpContext.Session.Clear();
await Authenticate(validatePeople.Model, roleName, getToolkit);
return Redirect(model.ReturnUrl);
}
private async Task<IActionResult> ShowLoginViewAsync(object model)
{
var schemeProvider = HttpContext.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
var shemas = await schemeProvider.GetAllSchemesAsync().FromAsyncResult(z => z.Where(x => x.Name.Equals("Facebook") || x.Name.Equals("Google")).ToList());
ViewBag.Shemas = shemas;
return View(model);
}
[HttpPost]
[AllowAnonymous]
public IActionResult ExternalLogin(string provider, string extReturnUrl = null)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
// Request a redirect to the external login provider.
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = extReturnUrl });
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
return Challenge(properties, provider);
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
{
await HttpContext.SignOutAsync("Cookies");
var externalModel = ExternalLoginModel.FromIdentity(HttpContext);
if (externalModel != null)
{
var user = default(Salespeople);
if (externalModel.Provider.Equals("Google"))
{
var request = await _salespeopleGetService.GetSalespeopleByPredicateAsNoTrackingAsync(p => p.GoogleKey.Equals(externalModel.Id));
if (!request.Success)
return RedirectToAction("Login", new { error = "You do not have a connected google account", returnUrl = returnUrl });
user = request.Model;
}
else if (externalModel.Provider.Equals("Facebook"))
{
var request = await _salespeopleGetService.GetSalespeopleByPredicateAsNoTrackingAsync(p => p.FacebookKey.Equals(externalModel.Id));
if (!request.Success)
return RedirectToAction("Login", new { error = "You do not have a connected facebook account", returnUrl = returnUrl });
user = request.Model;
}
return await Login(new LoginModel() { Login = user?.Email, Password = user?.Pass, ReturnUrl = returnUrl });
}
return RedirectToAction(nameof(Login));
}
private async Task Authenticate(Salespeople user, string role, int toolkitType)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.SId.ToString(), ClaimValueTypes.String),
new Claim(ClaimsIdentity.DefaultNameClaimType, user.Email),
new Claim(ClaimsIdentity.DefaultRoleClaimType, role),
new Claim(ClaimTypes.UserData,toolkitType.ToString()),
new Claim(ClaimTypes.Expiration, "")
};
ClaimsIdentity id = new ClaimsIdentity(claims, "ApplicationCookie", ClaimsIdentity.DefaultNameClaimType,
ClaimsIdentity.DefaultRoleClaimType);
_cpl = new ClaimsPrincipal(id);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, _cpl, (await _authService.GetAuthenticationPropertiesWithPermissions(user)).Model);
}
从日志中,外部登录的挑战已完成,但最终失败,并出现禁止错误。我看到了一些与我的问题相似的问题,但它们并没有帮助我。有什么解决方案可以解决吗?
添加调试输出日志(如果有帮助的话),第一个是身份验证失败,第二个是成功。这是针对同一用户的,但我不知道它具有不同的身份验证流程
--- failing ---
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2 GET https://localhost:5151/signin-facebook?code=AQDIS9CjmtoflJKzLhcwuPS0PvpcbuTYl_oq_0ZB1ykskn_yg8OezWJO2xQfvGGNulUDGK7hYu4kzPRRfXP5f04df-LbjSsWas7TuZJjD5_3dczQwtyNmkMUbLuE5l2pRLy8moqozj5ypljQdGeIxzh_ybho0jWifiYBibbzPYLSeER011pf9JR1PfRpVhI0hn3X7bQ-zz2lxTXLie4maGlIVPNKMg5e2g8U58Oj-8VVDghl4_A_yrfvadBhV4-WAWZ2pgdMgWU8cQC17MqxVDB6BPN75ptKM2aTVLftETZ_E5IFc2PYPyXncimU0XX0Ql7Tsx6ocTTsc-oJUMpSdUzx&state=CfDJ8DnbIAZdrZlOiRhsuDkovd9SFo8MwSuyOiFKGRVY9FUq03sttM2gpjCiozY40SvQNEuuoDhyWnw45lXPAUHdNAwKdqJcDRBjuTFoG3C5YiIsBX0Jde-broqU4tioNsTFZAxFxb1xzhsXkrRJsphH65yOPgbJlINl0MlHbt3M5olCCnbw1OTWt5MZMRugWyQ_si69LvVnrs2Si4-a2CajTwQvFck0xgqwhagoXYljz-R4bg2uKN2hpoXioA3SoXS83A
Microsoft.AspNetCore.Authentication.Facebook.FacebookHandler:Information: Error from RemoteAuthentication: An error occurred when retrieving Facebook user information (Forbidden). Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled..
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 294.3243ms 302
--- failing ---
--- not failing ---
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 19326.7074ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2 GET https://localhost:5151/signin-facebook?code=AQBRqh3qYM3FEikkxFKq_x4mX8S4XT0YzKwE9rvxIp3o3l70B9wkF1HZPkCxS-rQMwc2ETIr52BtTou520X0MxfHvSTQUK_JHRbgF5Hsk4cfzgUVHn0ypnhL4K18hd1_cLDsoWRBA1XAMz6zhMY7dzsm0pinXT_Y3vh2L-lBDlNThqgcNkWMs1yxbzSCZ9H8qq8ZuqqbTg1QBRuO0szuUG0_IDVl6CRqNfRnljzd2QA9SOX_KgocTA7jW8K_LPLlei_tEDxN0BXYYRTtv0tuDNoAHdcT0HrztxfDAtvoETesfJDUS0CJ21-4D7wnUvJ5_FXyJNVnbfUf6d3EC7mb5Osw&state=CfDJ8DnbIAZdrZlOiRhsuDkovd9Mt0AE6FLYwOyW7VgwOkat4BDyy6Dzfs19-26jZy48Z_x7nqOfA40UemgGkzZ-fzZfEvmXcMSw2XVNbk_ruIEsbG15K0Dwp5Bu5Ntdl1smvFirlUPlofXdOAlV8TTnakjACy4RgHy-qQ2oYmGkLlamfC_lvz2rhMboMx-6UYJY3GqpMiar4LlTmRTeD_crFAUtvTLWDiQFzJLavbHghn5U8DjFWCudkhmnq_DPolxJMA
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Cookies signed in.
--- not failing ---