Reputation: 2205
I have a spa application setup that is protected with IdentityServer4 using the Hybrid Authorization flow with OpenId Connect.
This spa application is able to call multiple ApiResources, as the logged in user, by requesting the access_token via
HttpContextAccessor.HttpContext.GetTokenAsync("access_token")
This is working great for multiple ApiResources. For example, my Spa application can call ApiResource1, ApiResource2, and ApiResource3 without any problems.
However, I have added a new ApiResource (i.e. ApiResource4) and I need to be able to call it from ApiResource1. However, when I try to call
HttpContextAccessor.HttpContext.GetTokenAsync("access_token")
from ApiResource1, the access_token is null so the call fails.
How can I make a call from ApiResource1 to ApiResource2 using the logged in User's token?
Maybe a better way of asking is, how to I get the logged in users access_token from ApiResource1?
My SPA application is setup like this:
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
})
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration.GetSection("IdentityServerOptions").GetValue<string>("BaseUrl");
options.RequireHttpsMetadata = true;
options.ClientId = Configuration.GetSection("IdentityServerOptions").GetValue<string>("ClientId");
options.ClientSecret = Configuration.GetSection("IdentityServerOptions").GetValue<string>("ClientSecret");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("ApiResource1");
options.Scope.Add("ApiResource2");
options.Scope.Add("ApiResource3");
options.Scope.Add("ApiResource4");
options.ResponseType = "code id_token";
});
My ApiResources are setup like this:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration.GetSection("IdentityServer").GetValue<string>("BaseUrl");
options.RequireHttpsMetadata = true;
options.ApiName = _AppName;
});
Upvotes: 2
Views: 740
Reputation: 4553
The HttpContext.GetTokenAsync("access_token")
extension method only works with Cookie Authentication. It will try to extract the token that is stored in the cookie. This is not available when you have an API using JWT authentication.
You have two options.
Use extension grant delegation as explained in the Identity Server docs http://docs.identityserver.io/en/release/topics/extension_grants.html#example-simple-delegation-using-an-extension-grant. This option is more complex to implement but it provides greater security.
Extract and forward the JWT from the Authorization
header. This option is as simple as getting the header from the Request and setting it on the headers of the HttpClient
before making the API request.
Upvotes: 2