NDUF
NDUF

Reputation: 707

How can I add AspNetIdentity to my API with IdentityServer4

I am building a .net core application, I have the IdentityServer4 and a MVC client running ok.

In the Startup of my IdentityServer, I can add the Asp.Net Identity successfully, and I get access both to the native UserManager and my UserContext (which extends IdentityDbContext).

I also have an API which my MVC client (or other clients) can call to get information about the logged in user. This API successfully relies on the Identity Server and can verify an access_token it receives, extract the sud, open the UserContext (defines in a common assembly), find the user and read any custom table I have added to the schema. Unfortunately I cannot get the API to register the Asp.Net Identity and therefore make use of the UserManager to see roles and other native tables.

Here's the IdentityServer Startup:

public void ConfigureServices(IServiceCollection services)
{

    services.AddIdentity<ApplicationUser, ApplicationRole>()
    .AddEntityFrameworkStores<UserContext>()
    .AddDefaultTokenProviders();

    services.AddMvc();

    services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddAspNetIdentity<ApplicationUser>()
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = builder =>
        builder.UseSqlServer(IdentityConnectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));
    })
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = builder =>
        builder.UseSqlServer(IdentityConnectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));
    });
}

With this Startup for the API, the request is processed successfully:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<UserContext>(options =>
    options.UseSqlServer(UserDbConnectionString));

    services.AddMvcCore()
    .AddAuthorization()
    .AddJsonFormatters();

    services
    .AddAuthentication("Bearer")
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;

        options.ApiName = "api1";
    });
}

The console output of the GET request (with token provided) is the following

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://localhost:5001/authorisation

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[2] Successfully validated the token.

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[8] AuthenticationScheme: BearerIdentityServerAuthenticationJwt was successfully authenticated.

info: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[8] AuthenticationScheme: Bearer was successfully authenticated.

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] Authorization was successful for user: Joe Bloke.

If I add Asp.Net Identity in the Startup of the API like this:

services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<UserContext>()
.AddDefaultTokenProviders();

Then the query fails, the log says the User is "null".

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://localhost:5001/authorisation

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed for user: (null).

info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.

This leads to a redirect to a login page that doesn't exist on the API and therefore a 404. I have tried adding a call to .AddAspNetIdentity() in the API but it doesn't seem to be recognised after AddIdentityServerAuthentication

Is it possible to have the API access the Asp.Net Identity UserManager? What do I need to do to fix this Authentication error?

Thanks

Upvotes: 4

Views: 1758

Answers (1)

Gerson Navarro
Gerson Navarro

Reputation: 11

Try use this code

services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })

Upvotes: 1

Related Questions