Well color me confused. I have an Angular app that is able to login using IdentityServer4. The Angular app is clientId web. When I decode the jwt, aud only has web.
I have an api resource created - api.
Now when I try and make a call to my .NET Core Api using the access token I get the audience validation failed error. Basically says it was expecting web and it got api as the audience.
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api";
options.SaveToken = true;
});
It works if I change the ApiName to web. The scopes listed in the jwt are all as I would expect. To add to my confusion even further, when I look in dbo.PersistedGrants, the audience listed in the data is
"Audiences": [
"http://localhost:5000/resources",
"api"
]
Client:
new Client
{
ClientId = "web",
ClientName = "Web",
AccessTokenType = AccessTokenType.Jwt,
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
AlwaysIncludeUserClaimsInIdToken = true,
RedirectUris = { "http://localhost:5005" },
PostLogoutRedirectUris = { "http://localhost:5005/logout" },
AllowedCorsOrigins = { "http://localhost:5005", "https://localhost:5005" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"role",
"api"
},
RequireConsent = false
}
API
new ApiResource("api", "API")
IdentityResource
return new[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResource("role", new[] { JwtClaimTypes.Role })
{
Required = true
}
};
I would expect the jwt to have the same values for the audience.
Is my understanding wrong or did I miss something configuring IdentityServer4?
Make sure you include scope: "api" in your auth request. If you don't explicitly specify what scopes you need when you're authenticating against IdentityServer (or any OIDC provider) you'll not get the api resource name in your jwt audience property.
Your request should look something like this:
http://my.identiyserverBaseUrl/connect/authorize?client_id=<CLIENT_ID>D&redirect_uri=<CLIENT_REDIRECT_URL>&response_type=token&scope=api&state=[OPTIONAL_STATE]
If you're using the npm oidc-client then your config object could look something like this:
const idsConfig = {
authority: 'YOUR_IDENITY_SERVER_BASE_URL',
client_id: 'CLIENT_ID',
redirect_uri: 'YOUR_CLIENT_REDIRECT_URL',
scope: 'api',
response_type: 'token',
client_secret: 'SECRET',
post_logout_redirect_url: `LOGOUT_REDIRECT_URL`,
userStore: new WebStorageStateStore({store: window.localStorage}),
automaticSilentRenew: true, // If you want to enable silent renew
silent_redirect_uri: 'REDIRECT_URL_FOR_SILENT_RENEW'
};
Note the scope. You can ask for multiple scopes like scope: 'api openid email'. If you ask for the openid scope you must include id_token in your response type.
Here's the documentation and here for the JavaScript client setup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With