I'm using .net core 2.2 with IdentityServer 4, trying to access additional API endpoints on the same server with an Access token, always receiving 401.
Startup.cs
services.AddLocalApiAuthentication();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.Authority = "https://localhost:5555";
options.RequireHttpsMetadata = false;
options.Audience = LocalApi.ScopeName;
});
services.AddIdentityServer(options =>
{
options.Caching.ClientStoreExpiration = TimeSpan.FromMinutes(10);
options.Caching.ResourceStoreExpiration = TimeSpan.FromMinutes(10);
options.Caching.CorsExpiration = TimeSpan.FromMinutes(10);
options.IssuerUri = "https://localhost:5555";
});
Configure :
app.UseHttpsRedirection();
app.UseIdentityServer();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
Endpoint:
[HttpGet]
[Route("v1/info")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = LocalApi.PolicyName)]
public async Task<ActionResult> GetAccountInfo()
Result :
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
Executing HttpStatusCodeResult, setting HTTP status code 401
UPDATE
API requests an access token from IdentityServer to access IdentityServer custom endpoint API. When trying to access IdentityServer endpoint api authenticated by this access token that received , I'm receiving 401
CodePudding user response:
After looking around on the source, seems like AddLocalApiAuthentication
method make use of its own authentication schemes, as we can see here and here.
So, if we want to keep default authentication scheme as IdentityServerAuthenticationDefaults.AuthenticationScheme
, just keep the startup config and change the action endpoint to [Authorize(AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme, Policy = IdentityServerConstants.LocalApi.ScopeName)]
.
But I was just curious... If I was right, this config was on our Identity provider service, so why should it accept a Jwt token from other Identity provider as we config it like
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.Authority = "https://localhost:5555"; // Other Identity provider here
options.RequireHttpsMetadata = false;
options.Audience = LocalApi.ScopeName;
});
Is there any special reason for this ? cause AFAIK, AddLocalApiAuthentication
was created embracing Identity provider to accept it own credentials, not from others.
UPDATE
I just take a look at your link... probably replace API 1
as Client might be more suitable.
Just simply change the config like this
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Some registers...
services.AddLocalApiAuthentication();
// No need for services.AddAuthentication(...).AddJwtBearer(...);
services.AddIdentityServer(); // This one take care of all the AddAuthentication stuff.
// Some registers...
}
public void Configure(IApplicationBuilder app)
{
// Some registers...
app.UseAuthentication();
// Some registers...
}
// Controller
[HttpGet]
[Route("v1/info")]
[Authorize] // This should be enough, and in case it's still 401, try beblow
//[Authorize(AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme, Policy = IdentityServerConstants.LocalApi.ScopeName)]
public async Task<ActionResult> GetAccountInfo()
Ensure to attach the token with Authorization
header format as Bearer eyskeu...
. This worked on .net 3.1, I don't have 2.x version for a while