状态 cookie 无效。处理远程登录时遇到错误。 ASP.NET Core MVC 外部社交登录

问题描述 投票:0回答:2

在没有 ASP.NET Core Identity 的 ASP.NET Core2.2 MVC Web 应用程序中实现外部社交登录时。成功登录 Google、Facebook、Twitter、LinkedIn 和 Microsoft 后,我在重定向回应用程序时收到以下错误。

处理请求时发生未处理的异常。 异常:无效的状态 cookie。未知地点

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

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

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。)

      //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");
        }
c# asp.net-mvc asp.net-core asp.net-core-mvc asp.net-identity
2个回答
4
投票

您似乎想在登录微软帐户后将请求重定向到

externallogincallback
。如果是这样,则不应将
microsoftOptions.CallbackPath
externallogincallback
设置。通过此设置,来自 Microsoft 的所有请求都将由 OAuth 中间件处理,而不是您自己的端点
externallogincallback

对于登录后重定向页面,您需要通过设置

return Challenge(authenticationProperties, provider);
 来传递 
authenticationProperties.authenticationProperties

请按照以下步骤操作:

  1. 使用
    REDIRECT URI
     更改 Azure 门户中的 
    https://localhost:xxx/signin-microsoft
  2. Startup.cs
    更改为

    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?}");
            });
        }
    }
    
  3. 家庭控制器

    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 });
        }
    }
    

0
投票

我通过确保在 Twitter 开发人员上创建的应用程序上配置的重定向路径恰好是“base_url/signin-twitter”来解决此问题。任何其他值都不起作用。

当用户单击登录/注册按钮时,您可以使用质询方法配置重定向路径:

Challenge(new AuthenticationProperties  {RedirectUri = "/redirect/path" }, "Twitter");

© www.soinside.com 2019 - 2024. All rights reserved.