Reputation: 42
I'm trying to setup a solution with the following:
- IdentityServer4 instance
- React / js client
- ASP.NET Core API (protected by IdentityServer)
Since I want to use roles and claims, I would like to use a reference token (id_token
) and have the API verify the claims against the IdentityServer.
Configuration for the IdentityServer instance:
"IdentityServer": {
"IdentityResources": [
"openid",
"email",
"phone",
"profile"
],
"ApiResources": [
{
"Name": "b2a6f5a1-9317-4b2f-bb02-c2f7cd70ce9a",
"DisplayName": "My API",
"ApiSecrets": [ { "Value": "<BASE 64 ENCODED SHA256 HASH OF SECRET>" } ]
}
],
"Clients": [
{
"Enabled": true,
"ClientId": "976d5079-f190-41a2-a6f6-be92470bacc0",
"ClientName": "My JS client",
"ClientUri": "http://localhost:3000",
"LogoUri": "logo.png",
"RequireClientSecret": false,
"AllowAccessTokensViaBrowser": true,
"RequireConsent": false,
"ClientClaimsPrefix": null,
"AccessTokenType": "reference",
"AllowedGrantTypes": [ "implicit" ],
"RedirectUris": [ "http://localhost:3000/authentication/login-callback" ],
"PostLogoutRedirectUris": [ "http://localhost:3000/authentication/logout-callback" ],
"AllowedCorsOrigins": [ "http://localhost:3000" ],
"AllowedScopes": [ "openid", "email", "phone", "profile", "b2a6f5a1-9317-4b2f-bb02-c2f7cd70ce9a" ]
}
]
}
Configuration for the (protected) API:
"Identity": {
"Authority": "https://localhost:44311",
"ApiName": "b2a6f5a1-9317-4b2f-bb02-c2f7cd70ce9a",
"ApiSecret": "<UNHASHED SECRET>"
}
Startup.cs for the API:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetValue<string>("Identity:Authority");
options.ApiName = Configuration.GetValue<string>("Identity:ApiName");
options.ApiSecret = Configuration.GetValue<string>("Identity:ApiSecret");
});
I query IdentityServer for an id_token with the following parameters:
export const Settings: any = {
authority: "https://localhost:44311",
post_logout_redirect_uri: "http://localhost:3000/authentication/logout-callback",
redirect_uri: "http://localhost:3000/authentication/login-callback",
response_type: "id_token",
scope: "openid email profile phone b2a6f5a1-9317-4b2f-bb02-c2f7cd70ce9a"
};
I get the following error: Requests for id_token response type only must not include resource scopes
.
If I change the scope to:
export const Settings: any = {
// ...
scope: "openid email profile phone" // removed (protected) api resource
};
it works and I get an id_token
like this:
{
"nbf": 1573798909,
"exp": 1573799209,
"iss": "https://localhost:44311",
"aud": "976d5079-f190-41a2-a6f6-be92470bacc0",
"nonce": "d768a177af684324b30ba73116a0ae79",
"iat": 1573798909,
"s_hash": "HbWErYNKpgsiOIO82IiReA",
"sid": "vVWVhLnVLiCMdLSBWnVUQA",
"sub": "90f84a26-f756-4923-9d26-6104eef031ac",
"auth_time": 1573798909,
"idp": "local",
"preferred_username": "noreply",
"name": "noreply",
"email": "[email protected]",
"email_verified": false,
"amr": [
"pwd"
]
}
Note that the audience is 976d5079-f190-41a2-a6f6-be92470bacc0
, which is the js client.
When I use this token on the protected API, it says:
Bearer error="invalid_token", error_description="The audience '976d5079-f190-41a2-a6f6-be92470bacc0' is invalid"
which is not that strange since the API has the id b2a6f5a1-9317-4b2f-bb02-c2f7cd70ce9a
.
So my question is: Where am I wrong? How do I get the token for the correct audience?
Upvotes: 0
Views: 1959
Reputation: 27528
The ID token
will be validated by your client app (React/js) app to get user claims , so the audience is your client app's client ID . A token passe to your web api should be validated by web api , so the audience is web api's name .
The ID token
contains information about an End-User which is not used to access protected resource , while Access token
allows access to certain defined server resources .You can set response_type
to id_token token
, and add api name/scope to scope
configuration . With implicit flow , after authentication , client will get one ID token
and one Access token
, you can now use access token to access the protected web api .
Upvotes: 1