![](/img/trans.png)
[英]System.InvalidOperationException: Unable to resolve service in ASP.NET Core
[英]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.