Внешний логин Twitter с Оуэном дает HTTP 403 (Запрещено) при обратном вызове - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь реализовать твиттер вход / вверх. В веб-приложении asp.net, но я получаю статус 403 http при последнем обратном вызове.

У меня настроены URL-адреса для обратных вызовов на портале приложений в Твиттере (я думаю, что они правильные)

Я даю немного контекста о том, что я пытаюсь сделать

  1. Перенаправить пользователя в твиттер sining
  2. Затем выполняется первый обратный вызов (здесь нет проблем), и я вызываю твиттер-API, чтобы получить информацию о пользователе.
  3. После получения сведений о пользователе я возвращаю результат запроса, чтобы я мог получить идентификатор пользователя, и для этого я указываю второй обратный вызов
  4. Второй обратный вызов не выполняется.

    Может кто-нибудь указать мне, что я делаю не так? Или как я могу отладить проблему? Мне известно, что твиттер проверяет, что URL-адрес обратного вызова должен быть установлен на портале для разработчиков приложений. Я получил это из этого вопроса вопрос

Вот мой код и конфиг

app.UseTwitterAuthentication(new TwitterAuthenticationOptions()
        {
            ConsumerKey = "key",
            ConsumerSecret = "qCLLsuS79YDkmr2DGiyjruV76mWZ4hVZ4EiLU1RpZkxOfDqwmh",
            Provider = new Microsoft.Owin.Security.Twitter.TwitterAuthenticationProvider
            {
                OnAuthenticated = (context) =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("urn:twitter:access_token", context.AccessToken));
                    context.Identity.AddClaim(new System.Security.Claims.Claim("urn:twitter:access_secret", context.AccessTokenSecret));
                    return Task.FromResult(0);
                }
            },
            BackchannelCertificateValidator = new Microsoft.Owin.Security.CertificateSubjectKeyIdentifierValidator(new[]
                   {
                      "A5EF0B11CEC04103A34A659048B21CE0572D7D47", // VeriSign Class 3 Secure Server CA - G2
                      "0D445C165344C1827E1D20AB25F40163D8BE79A5", // VeriSign Class 3 Secure Server CA - G3
                      "7FD365A7C2DDECBBF03009F34339FA02AF333133", // VeriSign Class 3 Public Primary Certification Authority - G5
                      "39A55D933676616E73A761DFA16A7E59CDE66FAD", // Symantec Class 3 Secure Server CA - G4
                      "‎add53f6680fe66e383cbac3e60922e3b4c412bed", // Symantec Class 3 EV SSL CA - G3
                      "4eb6d578499b1ccf5f581ead56be3d9b6744a5e5", // VeriSign Class 3 Primary CA - G5
                      "5168FF90AF0207753CCCD9656462A212B859723B", // DigiCert SHA2 High Assurance Server C‎A 
                      "B13EC36903F8BF4701D498261A0802EF63642BC3" // DigiCert High Assurance EV Root CA
                    }),
        });

Вызов входа в твиттер (я указываю первый URL обратного вызова, и этот работает)

[AllowAnonymous]
    public ActionResult TwitterRegistration()
    {
        string UrlPath = HttpContext.Request.Url.Authority;
        // pass in the consumerkey, consumersecret, and return url to get back the token
        NameValueCollection dict = new TwitterClient().GenerateTokenUrl(ConsumerKey, ConsumerSecret, "https://" + UrlPath + "/Account/TwitterRegistrationCallback");
        // set a session var so we can use it when twitter calls us back
        Session["dict"] = dict;
        // call "authenticate" not "authorize" as the twitter docs say so the user doesn't have to reauthorize the app everytime
        return Redirect("https://api.twitter.com/oauth/authenticate?oauth_token=" + dict["oauth_token"]);
    }

После обратного вызова я вызываю твиттер-API, чтобы получить пользовательские данные, которые тоже работают

[AllowAnonymous]
    public ActionResult TwitterRegistrationCallback(string oauth_token, string oauth_verifier)
    {
        TwitterClient twitterClient = new TwitterClient();
        NameValueCollection dict = (NameValueCollection)Session["dict"];
        NameValueCollection UserDictionary = HttpUtility.ParseQueryString(twitterClient.GetAccessToken(ConsumerKey, ConsumerSecret, oauth_token, oauth_verifier, dict));
        TwitterUserModel twitterUser = JsonConvert.DeserializeObject<TwitterUserModel>(twitterClient.GetTwitterUser(ConsumerKey, ConsumerSecret, UserDictionary));
        Session["twitterUser"] = twitterUser;

        // Returning challenge not working just redirecting to the action inn case of twitter as we are already authenitcated

        return new ChallengeResult("Twitter", Url.Action("ExternalRegistrationCallback", "Account", null));

    }

Но когда я возвращаю результат Challange, который в итоге вызывает

   context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);

это дает мне исключение ниже (то же самое в оригинальном вопросе)

Вот обратный вызов, который не вызывается

  // GET: /Account/ExternalRegistrationCallback
    [AllowAnonymous]
    public async Task<ActionResult> ExternalRegistrationCallback()
    {
        //TODO: Check
        if (User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Index", "Manage");
        }

        var loginInfo = await _authenticationManager.GetExternalLoginInfoAsync();


        if (Session["twitterUser"] != null)
        {
            //Workarround for twitter registration callback not using the challenge

            loginInfo = new ExternalLoginInfo();
            TwitterUserModel twitterUser = (TwitterUserModel)Session["twitterUser"];
            loginInfo.Email = twitterUser.email;
        }

        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }


        // Get the information about the user from the external login provider
        var info = await _authenticationManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return View("ExternalLoginFailure");
        }

        // Sign in the user with this external login provider if the user already has a login
        var result = await _signInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
        switch (result)
        {
            case SignInStatus.Success:
                //User is already registered We show error and tell the user to go back to login page?
                return RedirectToLocal((string)Session["ReturnUrl"]);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                //
                return RedirectToAction("SendCode", new { ReturnUrl = (string)Session["ReturnUrl"], RememberMe = false });
            case SignInStatus.Failure:
            default:
                // User is authenticated through the previous challange, So here needs to be saved

                RegistrationBasicViewModel model = (RegistrationBasicViewModel)Session["RegistrationModel"];

                //Check the user is in our db?
                ApplicationUser user = _userManager.FindByEmail(loginInfo.Email);
                IdentityResult identityResult;
                if (user == null)
                {

                    user = new ApplicationUser
                    {
                        UserName = loginInfo.Email,
                        Email = loginInfo.Email,
                        FirstName = model.FirstName,
                        LastName = model.LastName,
                        Nickname = model.Nickname
                    };
                    identityResult = await _userManager.CreateAsync(user);
                }
                else
                {
                    //TODO : Here we might want to tell the user it already exists
                    identityResult = IdentityResult.Success;

                        //IdentityResult.Failed(new string[] { "User already registered" });
                }

                if (identityResult.Succeeded)
                {

                    identityResult = await _userManager.AddLoginAsync(user.Id, info.Login);
                    if (identityResult.Succeeded)
                    {
                        //Adding the branch after te user is sucessfully added
                        await _signInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

                        _userBranchService.AddUserBranch(user.Id, model.BranchId);

                        //Redirect to home page
                        return RedirectToLocal((string)Session["ReturnUrl"]);
                    }
                }

                setPartnerBranchViewBag(model.PartnerId, (string) Session["partner"]);

                AddErrors(identityResult);
                return View("Register", model );



        }
    }

Twitter config

[HttpRequestException: Response status code does not indicate success: 403 (Forbidden).]
   System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() +223
   Microsoft.Owin.Security.Twitter.<ObtainRequestTokenAsync>d__23.MoveNext(

Ответы [ 2 ]

0 голосов
/ 01 августа 2018

Даже после добавления / signin-twitter к моим URL-адресам обратного вызова я получаю «Код состояния ответа не указывает на успех: 403 (Запрещено)». ошибка.

[HttpRequestException: Response status code does not indicate success: 403 (Forbidden).]
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() +121662
Microsoft.Owin.Security.Twitter.<ObtainRequestTokenAsync>d__23.MoveNext() +2389
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
Microsoft.Owin.Security.Twitter.<ApplyResponseChallengeAsync>d__12.MoveNext() +1091

Это исключение выдается, даже при использовании по умолчанию, из коробки шаблона Asp.NET MVC.

0 голосов
/ 06 июля 2018

Очевидно, что Оуэн использует URL-адрес по умолчанию (не URL-адрес, установленный в Challange)

URL-адрес по умолчанию - / signin-twitter. В моем случае мне пришлось настроить https://localhost:44378/signin-twitter в качестве одного из URL-адресов обратного вызова на портале приложения Twitter

...