簡體   English   中英

System.InvalidOperationException:idp 聲明丟失身份服務器 4.1.1 Asp.net 核心 3

[英]System.InvalidOperationException: idp claim is missing Identity server 4.1.1 Asp.net core 3

這是身份服務器配置的設置

var builder = services.AddIdentityServer(options =>
                {
                    options.Events.RaiseErrorEvents = true;
                    options.Events.RaiseInformationEvents = true;
                    options.Events.RaiseFailureEvents = true;
                    options.Events.RaiseSuccessEvents = true;
                    options.EmitStaticAudienceClaim = true;
                })
                .AddProfileService<ProfileService>()
                // this adds the config data from DB (clients, resources, CORS)
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
                            sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                // this adds the operational data from DB (codes, tokens, consents)
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
                            sql => sql.MigrationsAssembly(migrationsAssembly));
                    // this enables automatic token cleanup. this is optional.
                    options.EnableTokenCleanup = true;
                });
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    configuration.GetConnectionString("DefaultConnection"),
                    b => b.MigrationsAssembly("Falcon-Identity")));
            services.AddIdentity<ApplicationUser, IdentityRole>(
                    options =>
                    {
                        options.SignIn.RequireConfirmedAccount = true;
                        options.Password.RequireDigit = false;
                        options.Password.RequiredLength = 8;
                        options.Password.RequireLowercase = true;
                        options.Password.RequireUppercase = false;
                    })
                .AddEntityFrameworkStores<ApplicationDbContext>();

            // not recommended for production - you need to store your key material somewhere secure
            builder.AddDeveloperSigningCredential();
            builder.AddInMemoryApiScopes(Config.ApiScopes);

            // Register the IConfiguration instance which options binds against.
            services.Configure<IdentityServerViewModel>(configuration.GetSection("IdentityServer"));

應用配置

    app.UseRouting();
    app.UseIdentityServer();
    app.UseAuthorization();

客戶端配置

public static IEnumerable<Client> Clients(IConfiguration configuration) =>
            new Client[]
            {
                new Client
                {
                    ClientId = configuration.GetSection("IdentityServer:Client:ClientId").Value,
                    ClientName = configuration.GetSection("IdentityServer:Client:ClientName").Value,
                    //AllowedCorsOrigins = new List<string> { "http://localhost:4200","https://localhost:4200" },
                    AllowedGrantTypes = GrantTypes.Code,
                    AllowAccessTokensViaBrowser = bool.Parse(configuration.GetSection("IdentityServer:Client:AllowAccessTokensViaBrowser").Value),
                    AccessTokenLifetime=86400,
                    RequireConsent = bool.Parse(configuration.GetSection("IdentityServer:Client:RequireConsent").Value),
                    UpdateAccessTokenClaimsOnRefresh = bool.Parse(configuration.GetSection("IdentityServer:Client:UpdateAccessTokenClaimsOnRefresh").Value),
                    RedirectUris = LocalRedirectUris(configuration),
                    PostLogoutRedirectUris = LocalRedirectUris(configuration),
                    AllowedScopes = AllowedScopes(),
                    AllowOfflineAccess = bool.Parse(configuration.GetSection("IdentityServer:Client:AllowOfflineAccess").Value),
                    AccessTokenType = AccessTokenType.Jwt,
                    RequireClientSecret = bool.Parse(configuration.GetSection("IdentityServer:Client:RequireClientSecret").Value),
                    RequirePkce = bool.Parse(configuration.GetSection("IdentityServer:Client:RequirePkce").Value),
                    //AllowRememberConsent = true
                }
            };
        
        private static ICollection<string> AllowedScopes()
        {
            return new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.Email,
                AuthorizePolicy.apiScope
            };
        }
        
        // API scopes represent values that describe scope of access and can be requested by the scope parameter (OAuth)
        public static readonly IEnumerable<ApiScope> ApiScopes =
            new[]
            {
                new ApiScope(IdentityServerConstants.StandardScopes.OpenId),
                new ApiScope(IdentityServerConstants.StandardScopes.Profile),
                new ApiScope(IdentityServerConstants.StandardScopes.Email),
                new ApiScope(AuthorizePolicy.apiScope),
            };

帳號 controller

 if (ModelState.IsValid)
            {
                // validate username/password against in-memory store
                var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password,
                    model.RememberLogin, lockoutOnFailure: true);
                // validate username/password against in-memory store
                if (result.Succeeded)
                {
                    var user = await _userManager.FindByNameAsync(model.Username);
                    await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.Email, clientId: context?.Client.ClientId));

                    // only set explicit expiration here if user chooses "remember me". 
                    // otherwise we rely upon expiration configured in cookie middleware.
                    AuthenticationProperties props = null;
                    if (AccountOptions.AllowRememberLogin && model.RememberLogin)
                    {
                        props = new AuthenticationProperties
                        {
                            IsPersistent = true,
                            ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
                        };
                    };
    
                    // Add the additional claim to the Identity and token
                    var principal = await _claimsFactory.CreateAsync(user);
                    var claims = principal.Claims.ToList();
                    
                    // issue authentication cookie with subject ID and username
                    var isuser = new IdentityServerUser(user.Id)
                    {
                        DisplayName = user.UserName,
                        AdditionalClaims = claims    
                    };

                    await HttpContext.SignInAsync(isuser, props);

                    if (context != null)
                    {
                        if (context.IsNativeClient())
                        {
                            // The client is native, so this change in how to
                            // return the response is for better UX for the end user.
                            return this.LoadingPage("Redirect", model.ReturnUrl);
                        }

                        // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
                        return Redirect(model.ReturnUrl);
                    }

                    // request for a local page
                    if (Url.IsLocalUrl(model.ReturnUrl))
                    {
                        return Redirect(model.ReturnUrl);
                    }
                    else if (string.IsNullOrEmpty(model.ReturnUrl))
                    {
                        return Redirect("~/");
                    }
                    else
                    {
                        // user might have clicked on a malicious link - should be logged
                        throw new Exception("invalid return URL");
                    }
                }

                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId:context?.Client.ClientId));
                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
            }

錯誤

System.InvalidOperationException: idp claim is missing
   at IdentityServer4.Extensions.PrincipalExtensions.GetIdentityProvider(IIdentity identity)
   at IdentityServer4.Extensions.PrincipalExtensions.GetIdentityProvider(IPrincipal principal)
   at IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator.ProcessLoginAsync(ValidatedAuthorizeRequest request)
   at IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator.ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent)
   at IdentityServer4.Endpoints.AuthorizeEndpointBase.ProcessAuthorizeRequestAsync(NameValueCollection parameters, ClaimsPrincipal user, ConsentResponse consent)
   at IdentityServer4.Endpoints.AuthorizeEndpoint.ProcessAsync(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)
2021-01-07 07:14:50.419 +00:00 [ERR] An unhandled exception has occurred while executing the request.
System.InvalidOperationException: idp claim is missing
   at IdentityServer4.Extensions.PrincipalExtensions.GetIdentityProvider(IIdentity identity)
   at IdentityServer4.Extensions.PrincipalExtensions.GetIdentityProvider(IPrincipal principal)
   at IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator.ProcessLoginAsync(ValidatedAuthorizeRequest request)
   at IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator.ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent)
   at IdentityServer4.Endpoints.AuthorizeEndpointBase.ProcessAuthorizeRequestAsync(NameValueCollection parameters, ClaimsPrincipal user, ConsentResponse consent)
   at IdentityServer4.Endpoints.AuthorizeEndpoint.ProcessAsync(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)
   at IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
2021-01-07 08:36:56.305 +00:00 [INF] Starting IdentityServer4 version 4.1.1+cebd52f5bc61bdefc262fd20739d4d087c6f961f
2021-01-07 08:36:56.410 +00:00 [INF] Using the default authentication scheme Identity.Application for IdentityServer
2021-01-07 08:36:56.411 +00:00 [DBG] Using Identity.Application as default ASP.NET Core scheme for authentication
2021-01-07 08:36:56.412 +00:00 [DBG] Using Identity.External as default ASP.NET Core scheme for sign-in
2021-01-07 08:36:56.412 +00:00 [DBG] Using Identity.External as default ASP.NET Core scheme for sign-out
2021-01-07 08:36:56.413 +00:00 [DBG] Using Identity.Application as default ASP.NET Core scheme for challenge
2021-01-07 08:36:56.413 +00:00 [DBG] Using Identity.Application as default ASP.NET Core scheme for forbid
2021-01-07 08:36:56.865 +00:00 [DBG] Login Url: /Account/Login
2021-01-07 08:36:56.872 +00:00 [DBG] Login Return Url Parameter: ReturnUrl
2021-01-07 08:36:56.873 +00:00 [DBG] Logout Url: /Account/Logout
2021-01-07 08:36:56.873 +00:00 [DBG] ConsentUrl Url: /consent
2021-01-07 08:36:56.874 +00:00 [DBG] Consent Return Url Parameter: returnUrl
2021-01-07 08:36:56.875 +00:00 [DBG] Error Url: /home/error
2021-01-07 08:36:56.875 +00:00 [DBG] Error Id Parameter: errorId

從這些參考資料中嘗試了解決方案,但對我不起作用。

https://github.com/IdentityServer/IdentityServer4/issues/1792 https://github.com/IdentityServer/IdentityServer4/issues/1878

JWT 令牌

{
  "nbf": 1610250740,
  "exp": 1610250790,
  "iss": "https://falconidentityserver.azurewebsites.net",
  "aud": "https://falconidentityserver.azurewebsites.net/resources",
  "client_id": "Falcon_Identity_Server",
  "sub": "e413120a-2aa3-43e9-a450-eee670cca321",
  "auth_time": 1610250389,
  "idp": "local",
  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "e413120a-2aa3-43e9-a450-eee670cca321",
  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "admin@local.com",
  "AspNet.Identity.SecurityStamp": "d5fe7709-9d7d-4a08-a246-8e1ae0536bde",
  "IdentityServer": [
    "Read",
    "Create",
    "Update",
    "Delete"
  ],
  "jti": "CA316689F3B2F0F702CF10E63B6F4EA9",
  "sid": "23AF4158F934C003DD6552614E26E600",
  "iat": 1610250740,
  "scope": [
    "openid",
    "profile",
    "email"
  ],
  "amr": [
    "pwd"
  ]
}

您是否嘗試按照此處鏈接的說明配置 SecurityStampValidator 以保留 idp 聲明?

https://github.com/IdentityServer/IdentityServer4/issues/1878

顯然,在瀏覽器空閑一段時間后,ASP.NET Identity 會從 cookies 中刪除 idp 聲明。 為了防止這種情況,將以下內容添加到 ASP.NET 核心項目的 Startup.cs 中的 ConfigureServices 方法中。

builder.Services.Configure<SecurityStampValidatorOptions>(opts =>
{
    opts.OnRefreshingPrincipal = SecurityStampValidatorCallback.UpdatePrincipal;
});

(需要 IdentityServer4.AspNetIdentity 包)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM