Identity Server4 - 关联失败

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

当我将环境更新到 .NET 8 时,在一切正常之前(对于 .NET 6),我的问题出现了

错误页面 error page

客户端配置

JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";
    options.Authority = configuration["IdentityUrl"];
    options.RequireHttpsMetadata = false;

    options.ClientId = configuration["ClientId"];
    options.ClientSecret = configuration["ClientSecret"];
    options.ResponseType = "code";

    options.TokenValidationParameters = new TokenValidationParameters 
    { 
        NameClaimType = ClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    };
    options.SaveTokens = true;

    options.Scope.Add(IdentityServerConstants.StandardScopes.OpenId);
    options.Scope.Add(IdentityServerConstants.StandardScopes.Profile);
    options.Scope.Add(IdentityServerConstants.StandardScopes.Email);
    options.Scope.Add(AccountConstants.Scopes.All);
    options.Scope.Add(AccountConstants.Scopes.Roles);

    options.ClaimActions.MapJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role, JwtClaimTypes.Role);

    options.Events.OnRedirectToIdentityProvider = context =>
    {
        if (string.Equals(context.Request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
            string.Equals(context.Request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal))
        {
            context.Response.Clear();
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            context.Response.Headers["Location"] = "/Accounts/Account/SignOutNow";
            context.Properties.RedirectUri = $"{context.Request.Scheme}://{context.Request.Host}";
        }
        else
        {
            context.Properties.RedirectUri = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}";
            context.Properties.Items.Add(OpenIdConnectDefaults.RedirectUriForCodePropertiesKey, context.ProtocolMessage.RedirectUri);
            context.ProtocolMessage.State = options.StateDataFormat.Protect(context.Properties);
            context.Response.StatusCode = (int)HttpStatusCode.Redirect;
            context.Response.Headers["Location"] = context.ProtocolMessage.CreateAuthenticationRequestUrl();
        }

        context.HandleResponse();

        return Task.CompletedTask;
    };
});

身份服务器配置

services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityContext>()
.AddDefaultTokenProviders();

var builder = services.AddIdentityServer(options => {

    options.IssuerUri = "null";
    options.UserInteraction.LoginUrl = "/Accounts/SignIn";
    options.UserInteraction.LogoutUrl = "/Accounts/SignOut";
    options.Events.RaiseErrorEvents = true;
    options.Events.RaiseInformationEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseSuccessEvents = true;
})
.AddInMemoryIdentityResources(IdentityServerConfig.Ids)
.AddInMemoryApiScopes(IdentityServerConfig.ApiScopes)
.AddInMemoryApiResources(IdentityServerConfig.Apis)
.AddInMemoryClients(IdentityServerConfig.GetClients(configuration))
.AddAspNetIdentity<ApplicationUser>();

builder.Services.AddScoped<IProfileService, ProfileService>();

if (isProduction)
{
    var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(async (authority, resource, scope) =>
    {
        var context = new AuthenticationContext(authority);
        var credentials = new ClientCredential(configuration.GetValue<string>("AzureKeyVaultClientId"), configuration.GetValue<string>("AzureKeyVaultClientSecret"));
        var authenticationResult = await context.AcquireTokenAsync(resource, credentials);
        return authenticationResult.AccessToken;
    }));

    builder.AddSigningCredential(new X509Certificate2(Convert.FromBase64String(client.GetSecretAsync(configuration.GetValue<string>("AzureKeyVaultIdentityServer4Certificate")).Result.Value), configuration.GetValue<string>("AzureKeyVaultIdentityServer4CertificatePassword")));
}
else
{
    builder.AddDeveloperSigningCredential();
}

services.AddAuthentication()
    .AddIdentityServerAuthentication("IsToken", options =>
    {
        options.Authority = configuration.GetValue<string>("IdentityUrl");
        options.RequireHttpsMetadata = false;
        options.ApiName = AccountConstants.ApiNames.All;
    });

我试图在网上寻找解决方案,但大多数都指向对UseCookiePolicy()的修改,不幸的是它没有帮助。

我当前的配置

if (app.Environment.EnvironmentName == EnvironmentConstants.DevelopmentEnvironmentName)
{
    app.UseCookiePolicy(new CookiePolicyOptions
    {
        MinimumSameSitePolicy = SameSiteMode.Lax
    });
}
else
{
    app.UseCookiePolicy(new CookiePolicyOptions
    {
        MinimumSameSitePolicy = SameSiteMode.None,
        Secure = CookieSecurePolicy.Always
    });
}
.net asp.net-core identityserver4
1个回答
0
投票

如果您有多项服务;那么您必须配置数据保护 API 以使用相同的加密密钥(密钥环);否则,来自一个实例的 cookies/nonce/state 将不会被另一个实例接受。

我最近写了一篇关于 揭秘 ASP.NET Core 中 OpenID Connect 的状态和 Nonce 参数的博文,它可以让您深入了解 nonce/状态参数的内容。

请参阅配置 ASP.NET Core 数据保护

另一种方法是确保在整个身份验证周期中使用相同的服务实例。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.