dotnet core 2.0 authentication from angular 5

282 Views Asked by At

I'm having problems hitting a controller action when I'm not [AllowAnonymous].

I can run the method perfectly from Postman, but not from my UI and I just can't see what's fundamentally different. I'm running the app on localhost:4200, but I've added a CORS rule

    Startup.cs
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationUsers")));
        //          services.AddDbContext<TransactionsDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("TransactionsConnection")));

        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

        services.AddAuthentication()
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false; 
                options.SaveToken = true;                                                                                                       

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = "broker.Web.com",
                    ValidAudience = "broker.Web.com",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))
                };
            });


        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.WithOrigins("http://localhost:4200") //  .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });
        //services.AddAntiforgery();

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseStaticFiles();

        app.UseAuthentication();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        //app.UseCors(builder =>
        //  builder.WithOrigins("http://localhost:4200")
        //  .AllowAnyOrigin()
        //  .AllowAnyHeader()
        //  .AllowAnyMethod());

        app.UseCors("CorsPolicy");

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

Controller

[Authorize]
[Produces("Application/json")]
[Route("[controller]/[action]")]
public class SubsidiariesController : BaseController
{
    public SubsidiariesController(ApplicationDbContext userCtx, IHttpContextAccessor context, ILogger<ProductsController> logger, IConfiguration config) :
                base(userCtx, context, logger, config)
    {
    }

    //[AllowAnonymous]
    [HttpPost(Name = "GetSubsidiaries")]
    public List<Subsidiaries> GetSubsidiaries()
    {
        ApplicationUser currentUser = base.GetCurrentUser();
        List<Subsidiaries> subsidiaries = null;

        if (User != null)
        {
            SubsidiariesRepository subsidiariesRepository = new SubsidiariesRepository(Configuration.GetConnectionString("TransactionsConnection"));

            try
            {
                subsidiaries = subsidiariesRepository.GetForCustomer(currentUser.CustomersId);
            }
            catch (Exception e)
            {
                Logger.LogCritical(String.Format("Could not get sectors. Error: {0}\n{1}", e.Message, e.StackTrace));
            }
        }
        return (subsidiaries);
    }

}

Angular client

 ngOnInit() {

if (this.globalVars.token == null)
  this.router.navigate(['login']);


var headers = new HttpHeaders();

headers.append('Content-Type', 'text/plain');
headers.append('Authorization', 'Bearer ' + this.globalVars.token);

console.log("calling " + this.settings.settings.server + 'Subsidiaries/GetSubsidiaries');

//    http://localhost:54499/Subsidiaries/GetSubsidiaries
this.http.post(this.settings.settings.server + 'Subsidiaries/GetSubsidiaries',
  null, { headers: headers }).subscribe(
  res => {
    console.log(res);



  },
  err => {
    this.lastError = err.statusText;

    console.log("Error occured\n" + err);
  }
  );
}
1

There are 1 best solutions below

0
On

If you were to inspect your headers, you'd notice they are not being set. That's because the HttpHeaders are immutable, so all mutation operations return a new instance. So what you need to do when setting the headers is either:

let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'text/plain');
headers = headers.append('Authorization', 'Bearer ' + this.globalVars.token);

or cleaner:

let headers = new HttpHeaders()
  .append('Content-Type', 'text/plain')
  .append('Authorization', 'Bearer ' + this.globalVars.token)