已经为此苦苦挣扎了一段时间,让angular7客户端访问id4 Asp.Net core 2.2项目登录并返回jwt没问题,与angular7客户端访问Asp.Net core 2.2 api项目受保护的api都在下面id4保护。
jwt.io解码(值x'd出):
HEADER:ALGORITHM & TOKEN TYPE
{
"alg": "RS256",
"kid": "c672fc19f3ff652c5c8816cfac31bfcc",
"typ": "JWT"
}
PAYLOAD:DATA
{
"nbf": 1550161736,
"exp": 1550164736,
"iss": "https://localhost:44340",
"aud": "angularclient",
"nonce": "N0.88924643059608991550161727071",
"iat": 1550161736,
"at_hash": "A3fYyAynZIUQN5Z3ugvpvw",
"sid": "90c459301964e9f136a38b9b19d9b1e0",
"sub": "71765055-647D-432E-AFB6-0F84218D0247",
"auth_time": 1550161731,
"idp": "local",
"preferred_username": "xxxxxxxx",
"name": "xxxxxxxxxx",
"regid": "xxxxxxxxx",
"jseg": "xxxxx",
"jobid": "xxxxx",
"role": "xxxx",
"given_name": "xxxx",
"family_name": "Grexxxxenwald",
"email": "xxxxx",
"amr": [
"pwd"
]
}
ID4配置:
private static readonly string[] customClaimTypes = { "role", "jseg", "jobid", "regid", "api1" };
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResource("api1scope", customClaimTypes),
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new ApiResource[]
{
new ApiResource()
{
Name = "api1",
Description = "tsicApis",
ApiSecrets =
{
new Secret(Startup.Configuration.GetSection("StsConfig:STSTSICApisSecuredSecret").Value.Sha256())
},
Scopes =
{
new Scope()
{
Name = "api1",
DisplayName = "Scope for the api1 ApiResource",
},
},
UserClaims = customClaimTypes
}
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
var trustedClientSecrets = Startup.Configuration.GetSection("StsConfig:TrustedClientSecrets").Value;
var angularClientUrl = Startup.Configuration.GetSection("StsConfig:AngularClientUrl").Value;
var angularRedirectUris = Startup.Configuration.GetSection("StsConfig:AngularRedirectUris").Value;
var angularPostLogoutRedirectUris = Startup.Configuration.GetSection("StsConfig:AngularPostLogoutRedirectUris").Value;
var angularAllowedCorsOrigins = Startup.Configuration.GetSection("StsConfig:AngularAllowedCorsOrigins").Value;
var angularClientSecret = Startup.Configuration.GetSection("StsConfig:STSTSICApisSecuredSecret").Value;
var mvcClientSecrets = Startup.Configuration.GetSection("StsConfig:MVCClientSecrets").Value;
var mvcRedirectUris = Startup.Configuration.GetSection("StsConfig:MVCRedirectUris").Value;
var mvcFrontChannelLogoutUri = Startup.Configuration.GetSection("StsConfig:MVCFrontChannelLogoutUri").Value;
var mvcPostLogoutRedirectUris = Startup.Configuration.GetSection("StsConfig:MVCPostLogoutRedirectUris").Value;
// client credentials client
return new List<Client>
{
new Client
{
ClientName = "angularclient",
ClientId = "angularclient",
RequireClientSecret = true,
ClientSecrets = { new Secret(angularClientSecret) },
RequireConsent = true,
AllowRememberConsent = false,
AccessTokenType = AccessTokenType.Jwt,
AlwaysIncludeUserClaimsInIdToken = true,
AccessTokenLifetime = 33000,// 330 seconds, default 60 minutes
IdentityTokenLifetime = 3000,
AllowAccessTokensViaBrowser = true,
AllowedGrantTypes = GrantTypes.Implicit,
AllowedCorsOrigins = angularAllowedCorsOrigins.Split(','),
AllowedScopes =
{
"openid",
"profile",
"email",
"role",
"jseg",
"jobid",
"regid",
"api1",
"api1scope",
},
RedirectUris = angularRedirectUris.Split(','),
PostLogoutRedirectUris = angularPostLogoutRedirectUris.Split(',')
},
new Client
{
ClientId = "mvcclient",
ClientName = "mvcclient",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
ClientSecrets = { new Secret(mvcClientSecrets.Sha256()) },
RequireConsent = true,
AllowRememberConsent = false,
RedirectUris = mvcRedirectUris.Split(','),
FrontChannelLogoutUri = mvcFrontChannelLogoutUri,
PostLogoutRedirectUris = mvcPostLogoutRedirectUris.Split(','),
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
"openid",
"profile",
"api1"
}
},
};
}
角度app.module.ts:
export class AppModule {
constructor(
private oidcSecurityService: OidcSecurityService
) {
const openIDImplicitFlowConfiguration = new OpenIDImplicitFlowConfiguration();
openIDImplicitFlowConfiguration.storage = sessionStorage;
openIDImplicitFlowConfiguration.stsServer = environment.oidc.stsServer;
openIDImplicitFlowConfiguration.redirect_url = environment.oidc.redirect_url;
// The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer
// identified by the iss (issuer) Claim as an audience.
// The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience,
// or if it contains additional audiences not trusted by the Client.
openIDImplicitFlowConfiguration.client_id = 'angularclient';
openIDImplicitFlowConfiguration.response_type = 'id_token token';
openIDImplicitFlowConfiguration.scope = 'openid profile email api1scope';
openIDImplicitFlowConfiguration.post_logout_redirect_uri = environment.oidc.post_logout_redirect_uri;
// openIDImplicitFlowConfiguration.start_checksession = this.oidcConfigService.clientConfiguration.start_checksession;
openIDImplicitFlowConfiguration.silent_renew = true;
openIDImplicitFlowConfiguration.silent_renew_url = environment.oidc.silent_renew_url;
openIDImplicitFlowConfiguration.post_login_route = environment.oidc.post_login_route;
// HTTP 403
openIDImplicitFlowConfiguration.forbidden_route = '/forbidden';
// HTTP 401
openIDImplicitFlowConfiguration.unauthorized_route = '/unauthorized';
openIDImplicitFlowConfiguration.log_console_warning_active = environment.oidc.log_console_warning_active;
openIDImplicitFlowConfiguration.log_console_debug_active = environment.oidc.log_console_debug_active;
// id_token C8: The iat Claim can be used to reject tokens that were issued too far away from the current time,
// limiting the amount of time that nonces need to be stored to prevent attacks.The acceptable range is Client specific.
openIDImplicitFlowConfiguration.max_id_token_iat_offset_allowed_in_seconds = environment.oidc.max_id_token_iat_offset_allowed_in_seconds;
// openIDImplicitFlowConfiguration.iss_validation_off = false;
// configuration.FileServer = this.oidcConfigService.clientConfiguration.apiFileServer;
// configuration.Server = this.oidcConfigService.clientConfiguration.apiServer;
const authWellKnownEndpoints = new AuthWellKnownEndpoints();
authWellKnownEndpoints.issuer = environment.oidc.stsServer;
authWellKnownEndpoints.jwks_uri = `${environment.oidc.stsServer}/.well-known/openid-configuration/jwks`;
authWellKnownEndpoints.authorization_endpoint = `${environment.oidc.stsServer}/connect/authorize`;
authWellKnownEndpoints.token_endpoint = `${environment.oidc.stsServer}/connect/token`;
authWellKnownEndpoints.userinfo_endpoint = `${environment.oidc.stsServer}/connect/userinfo`;
authWellKnownEndpoints.end_session_endpoint = `${environment.oidc.stsServer}/connect/endsession`;
authWellKnownEndpoints.check_session_iframe = `${environment.oidc.stsServer}/connect/checksession`;
authWellKnownEndpoints.revocation_endpoint = `${environment.oidc.stsServer}/connect/revocation`;
authWellKnownEndpoints.introspection_endpoint = `${environment.oidc.stsServer}/connect/introspect`;
this.oidcSecurityService.setupModule(
openIDImplicitFlowConfiguration,
authWellKnownEndpoints
);
}
}
Asp.Net核心2.2 api项目start.cs:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServer4Strings:Authority");
options.RequireHttpsMetadata = Configuration.GetValue<bool>("IdentityServer4Strings:RequireHttpsMetadata");
options.ApiName = Configuration.GetValue<string>("IdentityServer4Strings:ApiName");
options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Jwt;
options.ApiSecret = Configuration.GetValue<string>("IdentityServer4Strings:STSTSICApisSecuredSecret");
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10); // that's the default
});
Asp.Net core 2.2 sts project start.cs:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
var identityServer = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddProfileService<IdentityWithAdditionalClaimsProfileService>()
//.AddTestUsers(TestUsers.Users)
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
})
.AddProfileService<IdentityWithAdditionalClaimsProfileService>()
.AddAspNetIdentity<ApplicationUser>();
services.AddTransient<IProfileService, IdentityWithAdditionalClaimsProfileService>();
Api authorize protection decorator (have tried both):
`
//[Authorize]
[Authorize(AuthenticationSchemes = "Bearer")]
`
Asp.Net core 2.2 sts start.cs:
`
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
var identityServer = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddProfileService<IdentityWithAdditionalClaimsProfileService>()
//.AddTestUsers(TestUsers.Users)
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
})
.AddProfileService<IdentityWithAdditionalClaimsProfileService>()
.AddAspNetIdentity<ApplicationUser>();
services.AddTransient<IProfileService, IdentityWithAdditionalClaimsProfileService>();
Asp.Net核心2.2 sts项目IdentityWithAdditionalClaims处理程序:
public IdentityWithAdditionalClaimsProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory, SqlDbContext Sql)
{
_userManager = userManager;
_claimsFactory = claimsFactory;
_context = Sql;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var principal = await _claimsFactory.CreateAsync(user);
var claims = principal.Claims.ToList();
var tsicCustomClaims = await GetTSICCustomClaims(claims);
claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();
claims.Add(new Claim(JwtClaimTypes.Scope, "api1"));
claims.Add(new Claim("regid", tsicCustomClaims.RegId.ToString()));
claims.Add(new Claim("jseg", tsicCustomClaims.JobPath));
claims.Add(new Claim("jobid", tsicCustomClaims.JobId.ToString()));
claims.Add(new Claim(JwtClaimTypes.Role, tsicCustomClaims.RoleName));
claims.Add(new Claim(JwtClaimTypes.GivenName, tsicCustomClaims.FirstName));
claims.Add(new Claim(JwtClaimTypes.FamilyName, tsicCustomClaims.LastName));
claims.Add(new Claim(IdentityServerConstants.StandardScopes.Email, tsicCustomClaims.EMail));
context.IssuedClaims = claims;
}
错误:
When accessing the protected api I get from Asp.Net core 2.2 api project:
[09:29:03 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler
Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateAudience(IEnumerable`1 audiences, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
[09:29:03 Information] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler
BearerIdentityServerAuthenticationJwt was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
[09:29:03 Information] IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler
Bearer was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
启动Asp.Net Core 2.2 sts项目时,我得到:
Seeding database...
Clients already populated
IdentityResources already populated
ApiResources already populated
Done seeding database.
[09:28:09 Information] IdentityServer4.Startup
Starting IdentityServer4 version 2.3.2.0
[09:28:09 Information] IdentityServer4.Startup
Using the default authentication scheme Identity.Application for IdentityServer
[09:28:09 Debug] IdentityServer4.Startup
Using Identity.Application as default ASP.NET Core scheme for authentication
[09:28:09 Debug] IdentityServer4.Startup
Using Identity.External as default ASP.NET Core scheme for sign-in
[09:28:09 Debug] IdentityServer4.Startup
Using Identity.External as default ASP.NET Core scheme for sign-out
[09:28:09 Debug] IdentityServer4.Startup
Using Identity.Application as default ASP.NET Core scheme for challenge
[09:28:09 Debug] IdentityServer4.Startup
Using Identity.Application as default ASP.NET Core scheme for forbid
[09:28:10 Debug] IdentityServer4.EntityFramework.TokenCleanup
Starting grant removal
Hosting environment: Development
Content root path: E:\Projects-STS\TSIC\TSIC.STS
Now listening on: https://localhost:44340
Application started. Press Ctrl+C to shut down.
[09:28:13 Debug] IdentityServer4.Startup
Login Url: /Account/Login
[09:28:13 Debug] IdentityServer4.Startup
Login Return Url Parameter: ReturnUrl
[09:28:13 Debug] IdentityServer4.Startup
Logout Url: /Account/Logout
[09:28:13 Debug] IdentityServer4.Startup
ConsentUrl Url: /consent
[09:28:13 Debug] IdentityServer4.Startup
Consent Return Url Parameter: returnUrl
[09:28:13 Debug] IdentityServer4.Startup
Error Url: /home/error
[09:28:13 Debug] IdentityServer4.Startup
Error Id Parameter: errorId
[09:28:25 Debug] IdentityServer4.Hosting.EndpointRouter
Request path /connect/authorize matched to endpoint type Authorize
[09:28:25 Debug] IdentityServer4.Hosting.EndpointRouter
Endpoint enabled: Authorize, successfully created handler: IdentityServer4.Endpoints.AuthorizeEndpoint
[09:28:25 Information] IdentityServer4.Hosting.IdentityServerMiddleware
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
[09:28:25 Debug] IdentityServer4.Endpoints.AuthorizeEndpoint
Start authorize request
[09:28:25 Debug] IdentityServer4.Endpoints.AuthorizeEndpoint
No user present in authorize request
[09:28:25 Debug] IdentityServer4.Validation.AuthorizeRequestValidator
Start authorize request protocol validation
[09:28:26 Debug] IdentityServer4.EntityFramework.Stores.ClientStore
angularclient found in database: True
[09:28:26 Debug] IdentityServer4.Stores.ValidatingClientStore
client configuration validation for client angularclient succeeded.
[09:28:27 Debug] IdentityServer4.EntityFramework.Stores.ResourceStore
Found ["openid", "profile", "email", "api1scope"] identity scopes in database
[09:28:27 Debug] IdentityServer4.EntityFramework.Stores.ResourceStore
Found [] API scopes in database
[09:28:27 Debug] IdentityServer4.EntityFramework.Stores.ResourceStore
Found ["openid", "profile", "email", "api1scope"] identity scopes in database
[09:28:27 Debug] IdentityServer4.EntityFramework.Stores.ResourceStore
Found [] API scopes in database
我想我靠近这里,只需要朝正确的方向推动即可。
我目前专注于这一行:
[09:28:27 Debug] IdentityServer4.EntityFramework.Stores.ResourceStore
Found [] API scopes in database
认为这与api项目错误有关:
IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
这让我很烦,因为数据库确实在SQL Server的dbo.ApiScopes中有一个条目:
Id Name DisplayName Description Required Emphasize ShowInDiscoveryDocument ApiResourceId
9 api1 Scope for the api1 ApiResource NULL 0 0 1 12
我很感谢您的帮助
答案 0 :(得分:0)
在角度配置中,您可以:
openIDImplicitFlowConfiguration.scope = 'openid profile email api1scope';
但是,它应该与api1的有效范围之一匹配:
openIDImplicitFlowConfiguration.scope = 'openid profile email api1';
Identity Server 4仅在您请求属于给定api的至少一个范围并且您的客户端被允许使用该范围时,才将Api资源添加为有效的令牌访问者。
答案 1 :(得分:0)
Vidmantas,感谢您的回复,我尝试了该操作,并且发生了相同的错误。然后,我很幸运并解决了(id令牌与访问令牌中指示的不同受众存在问题,以及如何通过Api项目startup.cs中的IdentityServer4配置设置id令牌aud:):
知道了,希望对其他人有帮助
登录后返回的角度客户端:
id令牌:
{
"nbf": 1550240640,
"exp": 1550273640,
"iss": "https://localhost:44340",
"aud": "https://localhost:44340/resources",
"client_id": "angularclient",
"sub": "71765055-647D-432E-AFB6-0F84218D0247",
"auth_time": 1550240638,
"idp": "local",
"regid": "xxxx",
"jseg": "xxxxx",
"jobid": "b0984a87-172a-436e-a382-e95de3e1059f",
"role": "xxxx",
"given_name": "xxxxx",
"family_name": "xxxx",
"email": "xxxx",
"scope": [
"openid",
"profile",
"email"
],
"amr": [
"pwd"
]
}
和访问令牌:
{
"nbf": 1550240640,
"exp": 1550243640,
"iss": "https://localhost:44340",
"aud": "angularclient",
"nonce": "N0.55036966062308791550240634889",
"iat": 1550240640,
"at_hash": "yNVxDVHkmEmUvurl7XlzuA",
"sid": "f54dee03793e7cc202b57f1d6de7622e",
"sub": "71765055-647D-432E-AFB6-0F84218D0247",
"auth_time": 1550240638,
"idp": "local",
"preferred_username": "TSICSuperUser",
"name": "xxxx",
"email": "xxxxx",
"email_verified": true,
"regid": "xxxxx",
"jseg": "xxxxx",
"jobid": "xxxxxxf",
"role": "xxxxx",
"given_name": "xxxx",
"family_name": "xxxxx",
"amr": [
"pwd"
]
}
注意不同的受众群体(aud:)
Asp.Net Core 2.2 Api项目startup.cs配置了IdentityServer4:
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServer4Strings:Authority");
options.RequireHttpsMetadata = Configuration.GetValue<bool>("IdentityServer4Strings:RequireHttpsMetadata");
options.ApiName = "api1";
options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Jwt;
options.ApiSecret = Configuration.GetValue<string>("IdentityServer4Strings:STSTSICApisSecuredSecret");
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10); // that's the default
});
而Bearer身份验证错误为:
2019-02-14 18:03:15.188 -07:00 [DBG] AuthenticationScheme: Bearer was not authenticated.
2019-02-14 18:04:04.360 -07:00 [INF] Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateAudience(IEnumerable`1 audiences, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
2019-02-14 18:04:04.430 -07:00 [INF] BearerIdentityServerAuthenticationJwt was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
2019-02-14 18:04:04.433 -07:00 [INF] Bearer was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: 'https://localhost:44340/resources'. Did not match: validationParameters.ValidAudience: 'api1' or validationParameters.ValidAudiences: 'null'.
错误的“ api1”:
Did not match: validationParameters.ValidAudience: 'api1'
引用startup.cs
.AddIdentityServerAuthentication
options.ApiName = "api1";
将Asp.Net Core 2.2 Api项目startup.cs更改为:
// critical for bearer authentication, the audience of the id token (set by Options.ApiName) is equal to this value
var idTokenAudience = $"{Configuration.GetValue<string>("IdentityServer4Strings:Authority")}/resources";
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("IdentityServer4Strings:Authority");
options.RequireHttpsMetadata = Configuration.GetValue<bool>("IdentityServer4Strings:RequireHttpsMetadata");
options.ApiName = idTokenAudience;
options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Jwt;
options.ApiSecret = Configuration.GetValue<string>("IdentityServer4Strings:STSTSICApisSecuredSecret");
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10); // that's the default
});
解决了这个问题。
2019-02-15 07:45:12.414 -07:00 [INF] Successfully validated the token.
2019-02-15 07:45:12.414 -07:00 [DBG] AuthenticationScheme: Bearer was successfully authenticated.