Reputation: 81
I am having issues with IdentityServer and I am learning it so there is a good chance I have something wrong. Basically I can run the App (.net core 5 app with identity server 4)
Below is my ConfigureServices
method:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
services.AddDbContext<BMProAppContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
.AddInMemoryApiScopes(deviceclients.GetApiScopes())
.AddInMemoryClients(deviceclients.GetClients());
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerJwt();
}
Here is my Configure
method:
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
When the app runs it issues a token successfully (I am using client credential flow)- then it throws an error as per below:
Token request success. fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.InvalidOperationException: No authentication handler is registered for the scheme 'Bearer'. The registered schemes are: Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId, idsrv, idsrv.external, IdentityServerJwt, IdentityServerJwtBearer. Did you forget to call AddAuthentication().AddSomeAuthHandler? at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme) at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthenticateAsync(AuthorizationPolicy policy, HttpContext context) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService) at IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at NSwag.AspNetCore.Middlewares.SwaggerUiIndexMiddleware.Invoke(HttpContext context) at NSwag.AspNetCore.Middlewares.RedirectToIndexMiddleware.Invoke(HttpContext context) at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Not sure what is wrong and have searched for answer but nothing seems to help :(
Any advice appreciated.
Upvotes: 2
Views: 857
Reputation: 2280
You are declaring a "Bearer"
scheme as the default authentication scheme, but you are forgetting the handler for that scheme.
If you use the defaultScheme
parameter when you call AddAuthentication
, you are setting the default scheme name and the application will try to use it when neccessary.
You need a registered handler with the same name to handle the request. Handlers also accept a scheme name when you register them. If you omit this parameter, an internal default value of each handler will be used, for example, jwtBearer internally uses "Bearer"
.
If you wanted to use the jwt bearer handler you'll need to use something like this:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Audience = "https://localhost:5000/";
options.Authority = "https://localhost:5000/identity/";
})
But I guess you pretend to use the IdentityServerJwt handler instead.
Just call AddIdentityServerJwt
without the scheme name parameter to add "IdentityServerJwt"
as the scheme name for this handler. That is the default name assigned internally by the handler.
services.AddAuthentication()
.AddIdentityServerJwt();
You could call your scheme whatever you want by specifying the scheme name:
services.AddAuthentication()
.AddIdentityServerJwt("MySchemeName");
Be aware that your Identity service doesn't need this handler if you don't need to protect resources on it, that is, if you want that in addition to being the Identity service, it acts as an API resource protected by itself.
And another issue... according with IdentityServer4 documentation: UseIdentityServer includes a call to UseAuthentication, so it’s not necessary to have both.
AddAuthentication(string defaultScheme)
?When you add a default scheme:
If it is not specified, we must use the Authorize attribute indicating the scheme or the schemes that should be used to construct the user's identity:
[Authorize(AuthenticationSchemes = "MyScheme")]
Upvotes: 1