Search code examples
c#asp.net-coreasp.net-identitymicroservicesidentityserver4

Using ASP.NET Core Identity with IdentityServer4 - Authentication


I'm trying to get my head around how to implement security in a microservices environment and am currently toying with the idea of using .NET Core Identity for User access management (usernames, passwords, hashing, etc) and IdentityServer4 for token based authentication and management.

This is because I want a veriety of clients to authenticate: a Blazer web site that will use usernames and passwords; other internal APIs which may use tokens; and a mobile app which will also use OAUTH token/refresh token logic.

I am trying to implement all this in one microservice so there is just one place all clients go to authenticate - a gate keeper of sorts.

My questions is: is this a good idea or should I be splitting the services?

Secondly: Wnen I'm testing my Login API call from postman I'm getting a 404 as the API is trying to redirect me to a login page. I would expect a 401 here instead as I've defined the authentication scheme to be Bearer.

Here is my code:

   public void ConfigureServices(IServiceCollection services)
        {
       services.AddControllers().AddNewtonsoftJson();
       var connectionString = Configuration.GetConnectionString("DefaultConnection");
                
       //add Users and Role system
        services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(connectionString));

            //this configures the dependancy injection for the UserManager in the Identity controller constructor.
        services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    
       //add Client tokens system
      
       var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
            services.AddIdentityServer()
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                })
               .AddAspNetIdentity<IdentityUser>();//required for Identity and IdentityServer4 to play nice together.
    
       //add authentication for this service
        services.AddAuthentication("Bearer")
           .AddIdentityServerAuthentication(options =>
           {
               options.Authority = "http://localhost:5001";//this service
               options.RequireHttpsMetadata = false;
               options.ApiName = "Identity";
           });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //  InitializeIdentityServerDatabase(app);

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseIdentityServer();

            app.UseAuthorization();
            
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }


Solution

  • The AddIdentityServerAuthentication will only kick in if you get a challenge back from the Authorization middleware, ie there is an authorize attribute on the controllers/actions.

    In general I also I always recommend that you separate IdentityServer from your clients and APIs to get a better separation of concerns.