无效的状态Cookie.处理远程登录时遇到错误.ASP.NET Core MVC外部社交登录 [英] Invalid state cookie. An error was encountered while handling the remote login. ASP.NET Core MVC external social login

查看:108
本文介绍了无效的状态Cookie.处理远程登录时遇到错误.ASP.NET Core MVC外部社交登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在没有ASP.NET Core身份的ASP.NET Core2.2 MVC Web应用程序中实现外部社交登录的同时.在成功使用Google,Facebook,Twitter,LinkedIn和Microsoft登录后,重定向回应用程序时出现错误消息.

While implementing external social login in ASP.NET Core2.2 MVC web application without ASP.NET Core Identity. I am getting below error while redirecting back to the application after successful sign in with Google, Facebook, Twitter, LinkedIn and Microsoft.

处理请求时发生未处理的异常.例外:无效的状态cookie.未知位置

An unhandled exception occurred while processing the request. Exception: Invalid state cookie. Unknown location

异常:处理远程登录时遇到错误.Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

Exception: An error was encountered while handling the remote login. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

以下是Startup.cs文件中的设置

Following are the settings in Startup.cs file

public void ConfigureServices(IServiceCollection services)
   {
       services.Configure<CookiePolicyOptions>(options =>
       {
           // This lambda determines whether user consent for non-essential cookies is needed for a given request.
           options.CheckConsentNeeded = context => true;
           options.MinimumSameSitePolicy = SameSiteMode.None;
       });

       services
           .AddAuthentication(options =>
           {
               options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
               options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
           })
           .AddCookie(options =>
           {
               options.Cookie.IsEssential = true;
           })
           .AddGoogle(options =>
           {
               options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
               options.ClientId = Configuration["Authentication:Google:ClientId"];
               options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
               options.CallbackPath = "/externallogincallback";             
           })
           .AddFacebook(facebookOptions =>
           {
               facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
               facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
               facebookOptions.CallbackPath = "/externallogincallback";                                        
           })
           .AddLinkedIn(linkedinOptions =>
           {
               linkedinOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
               linkedinOptions.ClientId = Configuration["Authentication:LinkedIn:ClientId"];
               linkedinOptions.ClientSecret = Configuration["Authentication:LinkedIn:ClientSecret"];
               linkedinOptions.CallbackPath = "/externallogincallback";                    
           })
           .AddTwitter(twitterOptions =>
           {
               twitterOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
               twitterOptions.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
               twitterOptions.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
               twitterOptions.CallbackPath = "/Home/externallogincallback";                    
           }).AddMicrosoftAccount(microsoftOptions =>
           {
               microsoftOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
               microsoftOptions.ClientId = Configuration["Authentication:Microsoft:ClientId"];
               microsoftOptions.ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"];
               microsoftOptions.CallbackPath = "/externallogincallback";
           });
       services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
   }

以下是HomeController.cs的详细信息(由于我没有使用Identity,所以我需要专门定义重定向URL.)

Following are the details of HomeController.cs (As I am not using Identity so I need to define redirect url specifically.)

      //Action to issue a challange to google login
        public IActionResult LogInMicrosoft(string provider)
        {
            //provider = Microsot or Google or LinkedIn or Twitter or Facebook
            provider = "Microsoft";
            //Issue a challenge to external login middleware to trigger sign in process
            //return new ChallengeResult(provider);

            var authenticationProperties = new AuthenticationProperties
            {
                RedirectUri = Url.Action("externallogincallback")
            };

            return Challenge(authenticationProperties, provider);
            //return new ChallengeResult(provider);
        }

        //Callback action to retrive signin user details
        //public IActionResult externallogincallback(string returnUrl = null, string remoteError = null)\
        public IActionResult externallogincallback()
        {
            //Here we can retrieve the claims
            // read external identity from the temporary cookie
            //var authenticateResult = HttpContext.GetOwinContext().Authentication.AuthenticateAsync("ExternalCookie");
            var result = HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            if (result.Result?.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }

            // retrieve claims of the external user
            var externalUser = result.Result.Principal;
            if (externalUser == null)
            {
                throw new Exception("External authentication error");
            }

            // retrieve claims of the external user
            var claims = externalUser.Claims.ToList();

            // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
            // depending on the external provider, some other claim type might be used
            //var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
            var userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            if (userIdClaim == null)
            {
                throw new Exception("Unknown userid");
            }

            var externalUserId = userIdClaim.Value;
            var externalProvider = userIdClaim.Issuer;

            // use externalProvider and externalUserId to find your user, or provision a new user

            return RedirectToAction("Privacy", "Home");
        }

推荐答案

似乎您希望在使用Microsoft帐户之后将请求重定向到 externallogincallback .如果是这样,则不应将 microsoftOptions.CallbackPath 设置为 externallogincallback .使用此设置,来自Microsoft的所有请求将由OAuth中间件处理,而不是您自己的终结点 externallogincallback .

It seems you want to redirect the request to externallogincallback after sigin the microsoft account. If so, you should not set microsoftOptions.CallbackPath with externallogincallback. With this setting, all the request from Microsoft will be handled by OAuth Middleware instead of your own endpoint externallogincallback.

对于签名后的重定向页面,您需要通过设置 authenticationProperties.authenticationProperties

For redirect page after sign, you need to pass return Challenge(authenticationProperties, provider); by setting the authenticationProperties.authenticationProperties

请按照以下步骤操作:

  1. 使用 https://localhost:xxx/signin-microsoft
  2. 在Azure门户中更改 REDIRECT URI
  3. 使用

  1. Change the REDIRECT URI in Azure portal with https://localhost:xxx/signin-microsoft
  2. Change Startup.cs with

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });


        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                //options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.Cookie.IsEssential = true;
                //options.Cookie.SameSite = SameSiteMode.None;
            })
            .AddMicrosoftAccount(microsoftOptions =>
            {
                microsoftOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                microsoftOptions.ClientId = Configuration["Authentication:Microsoft:ClientId"];
                microsoftOptions.ClientSecret = Configuration["Authentication:Microsoft:ClientSecret"];                    
            });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

  • HomeController

  • HomeController

    public class HomeController : Controller
    {
        //Action to issue a challange to google login
        public IActionResult LogInMicrosoft(string provider)
        {
            //provider = Microsot or Google or LinkedIn or Twitter or Facebook
            provider = "Microsoft";
            var authenticationProperties = new AuthenticationProperties
            {
                RedirectUri = Url.Action("externallogincallback")
            };
            return Challenge(authenticationProperties, provider);
        }
    
        [Route("/[action]")]
        public async Task<IActionResult> externallogincallback()
        {
            var request = HttpContext.Request;
            //Here we can retrieve the claims
            // read external identity from the temporary cookie
            //var authenticateResult = HttpContext.GetOwinContext().Authentication.AuthenticateAsync("ExternalCookie");
            var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    
            if (result.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }
    
            // retrieve claims of the external user
            var externalUser = result.Principal;
            if (externalUser == null)
            {
                throw new Exception("External authentication error");
            }
    
            // retrieve claims of the external user
            var claims = externalUser.Claims.ToList();
    
            // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
            // depending on the external provider, some other claim type might be used
            //var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
            var userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            if (userIdClaim == null)
            {
                throw new Exception("Unknown userid");
            }
    
            var externalUserId = userIdClaim.Value;
            var externalProvider = userIdClaim.Issuer;
    
            // use externalProvider and externalUserId to find your user, or provision a new user
    
            return RedirectToAction("Privacy", "Home");
        }
        public IActionResult Index()
        {
            return View();
        }
    
        public IActionResult Privacy()
        {
            return View();
        }
    
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
    

  • 这篇关于无效的状态Cookie.处理远程登录时遇到错误.ASP.NET Core MVC外部社交登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆