禁止Facebook身份验证

时间:2019-09-16 15:08:02

标签: c# .net facebook authentication asp.net-core

几个月前开始的与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 ---

0 个答案:

没有答案
相关问题