繁体   English   中英

net.core / asp.net 身份 / openid 连接中的关联失败

[英]Correlation failed in net.core / asp.net identity / openid connect

当 Azure AD 用户登录时出现此错误(我能够在之后获得用户的声明),我使用 OpenIdConnect 与 asp.net 身份核心在 net.core 2.0 上的组合

处理请求时发生未处理的异常。 例外:关联失败。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+d__12.MoveNext()

痕迹:

例外:关联失败。 Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+d__12.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) System.Runtime.CompilerServices.TaskAwaiter.GetResult() Microsoft。 AspNetCore.Authentication.AuthenticationMiddleware+d__6.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+d__7.MoveNext()

关联失败

这是我的 Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BPT.PC.IdentityServer.Data;
using BPT.PC.IdentityServer.IdentityStore;
using BPT.PC.IdentityServer.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace BPT.PC.IdentityServer.Web
{
    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.AddIdentity<User, Role>()
                .AddUserStore<UserStore>()
                .AddRoleStore<RoleStore>()
                .AddDefaultTokenProviders();

            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddDbContext<IdentityServerDb>(options => options.UseSqlServer(Configuration.GetConnectionString("IdentityServerDb")));

            services.AddMvc();
            services.AddAuthentication(auth =>
            {
                auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect("AzureAD", opts =>
            {
                Configuration.GetSection("OpenIdConnect").Bind(opts);
                opts.RemoteAuthenticationTimeout = TimeSpan.FromSeconds(120);
                opts.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                opts.CorrelationCookie = new Microsoft.AspNetCore.Http.CookieBuilder
                {
                    HttpOnly = false,
                    SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None,
                    SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None,
                    Expiration = TimeSpan.FromMinutes(10)
                };

                opts.Events = new OpenIdConnectEvents()
                {
                    OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
                    OnRemoteFailure = OnRemoteFailure,
                    OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
                };
                //opts.Events = new OpenIdConnectEvents
                //{
                //    OnAuthorizationCodeReceived = ctx =>
                //    {
                //        return Task.CompletedTask;
                //    }
                //};
            });

            //services.ConfigureApplicationCookie(options =>
            //{
            //    // Cookie settings
            //    options.Cookie.HttpOnly = true;
            //    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            //    options.SlidingExpiration = true;
            //});
        }

        private Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext arg)
        {
            return Task.FromResult(0);
        }

        private Task OnRemoteFailure(RemoteFailureContext arg)
        {
            return Task.FromResult(0);
        }

        private Task OnRedirectToIdentityProvider(RedirectContext arg)
        {
            return Task.FromResult(0);
        }

        // 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.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Account}/{action=Login}/{id?}");
            });
        }
    }
}

我的 appsettings.json:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "ConnectionStrings": {
    "IdentityServerDb": "Server=localhost;Database=IdentityServer;Trusted_Connection=True;MultipleActiveResultSets=true"
  },

  "OpenIdConnect": {
    "ClientId": "xxxxx",
    "Authority": "https://login.microsoftonline.com/xxxxx/",
    "PostLogoutRedirectUri": "/Account/SignoutOidc",
    "CallbackPath": "/Account/SigninOidc",
    "UseTokenLifetime": true,
    "RequireHttpsMetadata": false,
    //"ResponseType": "code id_token",
    "ClientSecret": "xxx",
    "Resource": "https://graph.microsoft.com/"
  }
}

和实施:

[HttpGet]
public IActionResult CorpLogin()
{
  var authProperties = _signInManager
                .ConfigureExternalAuthenticationProperties("AzureAD",
     Url.Action("SigninOidc", "Account", null, Request.Scheme));

   return Challenge(authProperties, "AzureAD");
}

[HttpPost]
public IActionResult SigninOidc([FromForm]object data)
{
//this never runs
   return Ok();
}

如果您在 localhost 上使用 Chrome,您可能会遇到 Chrome cookie 处理行为的变化。

要进行验证,请导航到 chrome://flags/ 并将“没有 SameSite 的 Cookie 必须是安全的”更改为“已禁用”。

如果该更改解决了问题,并且您想永久修复它(即不依赖 chrome 标志修复), 则此 thinktecture 帖子将讨论潜在问题以及旧 iOS safari 版本所需的一些修复。

在 Chrome 上的 Blazor 中使用 .net Identity 使用 Google 登录时,我遇到了这个问题。 我有一个新的要求,让它在没有 https 的情况下工作,它在 https 下工作得很好。

我阅读了多个答案变体

app.UseCookiePolicy(new CookiePolicyOptions()
{
    MinimumSameSitePolicy = SameSiteMode.None
});

我希望我能早点阅读@dbruning 的答案文章。 它在文章中提到,在其他任何地方都没有提到: Please note: The setting SameSite=None will only work if the cookie is also marked as Secure and requires a HTTPS connection. 该方法的智能感知摘要没有提到这一点,我认为它绝对应该......

所以在那之后我只是尝试使用SameSiteMode.Lax ,它再次对我有用。 默认 blazor 项目 startup.cs 无需其他更改

app.UseCookiePolicy(new CookiePolicyOptions()
{
    MinimumSameSitePolicy = SameSiteMode.Lax
});

我终于找到了解决方案,我会在这里发布以防万一有人遇到类似问题。

看起来主要问题是我的重定向 URI 与 CallBackPath 相同:

"CallbackPath": "/Account/SigninOidc"

var authProperties = _signInManager .ConfigureExternalAuthenticationProperties("AzureAD", Url.Action("SigninOidc", "Account", null, Request.Scheme));

好吧,这是我更正后的 Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BPT.PC.IdentityServer.Data;
using BPT.PC.IdentityServer.IdentityStore;
using BPT.PC.IdentityServer.Models;
using BPT.PC.IdentityServer.Web.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

namespace BPT.PC.IdentityServer.Web
{
    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.AddIdentity<User, Role>()
                .AddUserStore<UserStore>()
                .AddRoleStore<RoleStore>()
                .AddDefaultTokenProviders();

            services.AddMemoryCache();
            services.AddDistributedMemoryCache();
            services.AddDbContext<IdentityServerDb>
                (options => options.UseSqlServer(Configuration.GetConnectionString("IdentityServerDb")));

            services
                .AddMvc();
            services
                .AddAuthentication(auth =>
                {
                    auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    auth.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                })
                .AddCookie()
                .AddOpenIdConnect("AzureAD", "AzureAD", options =>
                {
                    Configuration.GetSection("AzureAD").Bind(options); ;
                    options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
                    options.RemoteAuthenticationTimeout = TimeSpan.FromSeconds(120);
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.RequireHttpsMetadata = false;
                    options.SaveTokens = true;
                });

            services.AddSingleton(Configuration.GetSection("OpenIdConnectProviderConfiguration").Get<OpenIdConnectProviderConfiguration>());

        }
        // 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.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Account}/{action=Login}/{id?}");
            });
        }
    }
}

最后的实现:

[HttpGet]
public IActionResult CorpLogin()
    {
        var authProperties = _signInManager
            .ConfigureExternalAuthenticationProperties("AzureAD",
            Url.Action("LoggingIn", "Account", null, Request.Scheme));

        return Challenge(authProperties, "AzureAD");
    }

appsettings.json 是一样的。

我遇到了一个非常相似的问题,整个线程中发布的答案都没有对我有用。 我将描述我是如何找到解决方案的,以防它可以帮助其他人。

就我而言,我有一个带有 ASP.NET Core 3.1(从 1.x 迁移)的 Web 应用程序,并在Startup.csConfigureServices方法中使用以下代码段实现了身份验证(如此所述):

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));

这里可以看出,抛出的错误具有比该线程上描述的更简单的堆栈跟踪。

最后,问题在于cookie 没有被设置为安全的 为此,我刚刚在上面粘贴的services.AddAuthentication之前添加了以下代码片段。

services.Configure<CookiePolicyOptions>(options =>
{
    options.Secure = CookieSecurePolicy.Always;
});

此外,我在Startup.csConfigure()方法中调用app.UseRouting() app.UseCookiePolicy()之前添加了对 app.UseCookiePolicy() 的调用。

仅供参考:我遇到了同样的问题,这让我花了将近 1 天的时间来调查这个问题。 最后我发现从我的 startup.cs 中删除以下代码后一切正常: CookiePolicyOptions cookiePolicy = new CookiePolicyOptions() { Secure = CookieSecurePolicy.Always, };

我正在与 Microsoft 支持团队跟进此事,如果得到任何回复,我会及时更新。

我的问题是我机器上的时钟(我使用的是虚拟机)没有设置正确的时间。 它落后了几天,因为我在上次使用虚拟机后暂停了它。

所以解决方案是简单地将时钟调整为正确的时间。

当您尝试访问在 OIDC 设置中分配为“回调路径”的 URL 时,会发生这种情况。

要解决此问题,请将您的回调路径更改为“MyController/MyAction”之类的东西,这会将您重定向到您的特定 URL,在您的情况下为“/Account/SigninOidc”。

就我而言,我不得不去 Visual Studio 菜单,

Project=> Application Properties => Debug tab = Enable SSL true

并且在 FB Developer 账户的实际 OAuth 配置中,设置使用 https。 这已经解决了。 其他人可能会有不同的复杂问题。 就我而言,这已经对其进行了排序。

感谢 Tim.Tang 的回答,我弄清楚了导致我在 Core 2.2 上出现错误的原因。 除了在 Startup.cs > ConfigureServices 方法中删除 cookie 策略的代码时出现错误之外,它是相似的:

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

这是因为我忘了也删除app.UseCookiePolicy(); Configure方法中的代码。

把它放在 Startup.Configure() 的顶部,在其他中间件使用之前:

app.UseCookiePolicy(new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict
});

使用 IdentityServer 4.1.2、.NET Core 5 测试

在我的配置方法顶部使用它解决了我的问题

app.UseCookiePolicy(new CookiePolicyOptions()
    {
        MinimumSameSitePolicy = SameSiteMode.Lax
    });

当您在 http 上运行身份服务器并且浏览器是 chrome 时,通常会发生此问题,尝试在 IE Edge 上运行应用程序或使用 https 始终可以解决此问题

我有同样的问题

例外:关联失败。

在尝试向 AzureAD 验证我的 dotNet Core 3 应用程序时。

将我的启动配置文件更改为“ Project ”并添加一个 https 应用程序 URL(“https://localhost:5001;http://localhost:5000”)实际上对我有用!

在我的情况下,我必须在 launchSettings.json 文件中提供一个随机的 sslPort,在它为 0 之前。

"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
  "applicationUrl": "http://localhost:17950",
  "sslPort": 44312
}

我今天在 Visual Studio 中调试时突然在每个浏览器中都遇到了这个问题,并通过从 Kestrel 切换到 IIS Express 来修复它。

我遇到了这个问题,结果证明是区分大小写的 cookie 路径。 我将redirect_uri 小写(因为它们区分大小写)。 而且我认为中间件根据“basePath”设置cookie路径。

我的创业公司最终看起来像这样:

services.AddAuthentication().AddMicrosoftAccount(microsoftOptions =>
    {
            microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"];
            microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"];
            // The path is case sensitive so just override
            microsoftOptions.CorrelationCookie.Path = "/"; 
            microsoftOptions.Events.OnRedirectToAuthorizationEndpoint = context =>
            {
                var redirectUriParam = "redirect_uri";

                var uri = new UriBuilder(context.RedirectUri);
                var qs = HttpUtility.ParseQueryString(uri.Query);

                string returnUrl = qs.Get(redirectUriParam);
                if (!string.IsNullOrEmpty(returnUrl))
                {
                    // The return urls are case sensitive so force this to lower case
                    qs.Set(redirectUriParam, returnUrl.ToLower());
                }

                uri.Query = qs.ToString();
                string redirectUrl = uri.Uri.ToString();
                context.Response.Redirect(redirectUrl);
                return Task.CompletedTask;
            };
        });

另见: https ://github.com/IdentityServer/IdentityServer3/issues/1876

就我而言,在使用 Nginx-Ingress 作为反向代理在 Kubernetes 中托管 webapp 时出现此错误。

我注意到 cookie 存储在浏览器中,但路径不正确。 路径是“/signin-oidc”,而不是“/X/Y/signin-oidc”,这就是浏览器在导航到“/X/Y/signin-oidc”时没有将cookie发送到webapp服务器的原因。

我的解决方法是将 NonceCookie 和 CorrelationCookie 的 Cookie 路径设置为“/X/Y/signin-oidc”

builder.AddOpenIdConnect("oidc", options =>
{
    ...
    options.NonceCookie.Path = "/X/Y/signin-oidc";
    options.CorrelationCookie.Path = "/X/Y/signin-oidc";
});

在 .NET 上安装应用程序 6. 该应用程序在 HTTP 上,因为 HTTPS 由负载均衡器提供。 我对 Seznam Oauth 提供商(捷克共和国的 OAuth 提供商/电子邮件服务)的 OAuth 有问题。

对我来说,解决问题的代码是:

options.CorrelationCookie.SameSite = SameSiteMode.Lax;

在 Startup.cs ConfigureServices 方法中

services.AddOAuth<CustomOAuthAuthenticationOptions, CustomOAuthClientAuthentication>("MyAuthScheme", "MyAuthScheme", options =>
{
    options.CorrelationCookie.SameSite = SameSiteMode.Lax;
});

设置 CorrelationCookie 有助于解决问题。 也许它适用于其他供应商。

我不能使用UseCookiePolicy扩展方法的原因是我们在我们的应用程序中支持不同的身份验证方法,这需要不同的 cookie 选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM