9

I create .Net Core API and I configure the windows authentication. In my angular application I have to put in each request this option withCredentials : true. I do a put request but it return me that :

401 (Unauthorized) 401 unauthorized 401 network

I also try on post request and it doesn't work only get request work.

auth.service.ts :

updateUser(id,lastlogin,ac,lastlogoff,picture){
  return this.http.put(`${this.config.catchApiUrl()}User/`+ id , {
    id : id ,
    picture : picture,
    lastLogin : lastlogin ,
    lastLogoff : lastlogoff ,
    ac: ac
  },{
    headers : this.header,
    withCredentials : true
  })
}

auth.component.ts :

constructor(
private authService : AuthenticationService
) { }

loginToApplication(username :string){
    this.authService.updateUser(e["id"],lastLogin,e["ac"],e["lastLogoff"],e["picture"]).subscribe(
        console.log("enter"))
}

.Net Core API Update user controller :

[AllowAnonymous] // Even if I do this it doesn't work
[HttpPut("{id}")]
public async Task<ActionResult<User>> UpdateUser(int id, User user)
{
   try { 

        var ldapPath = Environment.GetEnvironmentVariable("path");
        var ldapUsername = Environment.GetEnvironmentVariable("user");
        var ldapPassword = Environment.GetEnvironmentVariable("psw");

        DirectoryEntry Ldap = new DirectoryEntry(ldapPath, ldapUsername, ldapPassword);

        DirectorySearcher searcher = new DirectorySearcher(Ldap);

        var users = await _context.Users.Include(t => t.Access).FirstOrDefaultAsync(t => t.Id == id);
        if (users == null)
        {
            return StatusCode(204);
        }

        if(users.Ac== 1 && user.Ac!= 1)
        {
            return BadRequest("You can't change an administrator profile");
        }

        searcher.Filter = "(SAMAccountName=" + users.Login.ToLower() + ")";

        SearchResult result = searcher.FindOne();

        if (result == null)
        {
            return NoContent();
        }

        DirectoryEntry DirEntry = result.GetDirectoryEntry();
        user.Lastname = DirEntry.Properties["sn"].Value.ToString();
        user.Fullname = DirEntry.Properties["cn"].Value.ToString();
        user.Firstname = DirEntry.Properties["givenname"].Value.ToString();
        user.Login = DirEntry.Properties["samaccountname"].Value.ToString().ToLower();
        user.Email = DirEntry.Properties["mail"].Value == null ? "No mail" : DirEntry.Properties["mail"].Value.ToString(); ;

        _context.Entry(users).CurrentValues.SetValues(user);
        _context.SaveChanges();
        return users;
        }
    catch (Exception ex)
    {
       return StatusCode(204,ex.Message);
    }

}

Even if I add [AllowAnonymous] on the top of the controller it doesn't work.

UPDATE: I have Cors in my project, startup.cs in ConfigureServices :

services.AddCors(options =>
{
    options.AddPolicy("AnyOrigin", builder =>
    {
        builder
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials();
    });
});

in Configure:

app.UseCors("AnyOrigin");

Moreover if I want to test on postman I have this error (also in get request but in my project get request work)

401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials that you supplied.

When I'm on my api web site (I use swagger), I have this :

Your connection is not private

user10863293
  • 770
  • 4
  • 11
  • 32
  • Have you included `.AllowCredentials()` in the CORS policy of your .net core api in the `Configure` method in `Startup.cs`? –  Apr 09 '19 at 09:47
  • @Arul yes I do this : services.AddCors(options => { options.AddPolicy("AnyOrigin", builder => { builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); – user10863293 Apr 09 '19 at 09:55
  • Where is your API deployed? Since you say the api on your localhost works fine, is your api and the client from which you are accessing the api are on the same domain? –  Apr 09 '19 at 10:08
  • @Arul my api is deployed on IIS and it is on the same domain – user10863293 Apr 09 '19 at 10:14
  • have you ever solved this? I have the same situation... trying for days to fix it... – sosNiLa Nov 13 '19 at 10:10
  • @sosNiLa I'm not sure but if i remember correctly I have the error because someone install a module in IIS which was webdav. So I have to configure my web.config in order to don't use webdav. – user10863293 Nov 13 '19 at 11:05
  • the app is only on my local machine so that cant be the case, but thanks for commenting. cheers – sosNiLa Nov 13 '19 at 11:33

3 Answers3

1

I had the same issue. Besides the setting the Cors settings correctly I did the following in Angular

Created a custom Interceptor to add withCredentials option set to true

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";

@Injectable()
export class CustomInterceptor implements HttpInterceptor { 
    
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        request = request.clone({
            withCredentials: true
        });
    
        return next.handle(request);
    }
}

Add the interceptor to app.module.ts

providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CustomInterceptor ,
      multi: true
    }
  ],

In my WebAPI I had the following settings

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

and

app.UseCors("CorsPolicy");

and finally made sure I had the [FromBody] in the controller for posts calls

    [HttpPost]
    [Route("AdvanaceCaseSearch")]
    public async Task<IEnumerable<AdvanceCaseResults>> AdvanaceCaseSearch(**[FromBody]** AdvanceCaseSearchParam reportparams)
    {
H20rider
  • 2,162
  • 5
  • 29
  • 47
0

First things first: can you make an authorized request with, say, a tool like Postman? If yes, then look at the request headers (and possibly payload) in the correct one, and figure out what's missing from the one sent by Angular.

Also, you have a CORS error in the console (among other things). A quick (&dirty) fix will be to enable CORS user-side (there's an addon CORS Anywhere for Firefox, and some command line options for Chrome), and check again.

Try that.

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • I can't test it on postman because my site url send me that : 401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials that you supplied. On all request but when I try my api on localhost it works – user10863293 Apr 09 '19 at 09:57
  • Well then - the problem isn't with Angular, it's with the request and, it seems, invalid credentials. – mbojko Apr 09 '19 at 09:58
-1

You need configure CORS for your Web API.

Refer link https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2 and link How to enable CORS in ASP.NET Core

Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
  • I alreay have core in my .net core project : services.AddCors(options => { options.AddPolicy("AnyOrigin", builder => { builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); And this app.UseCors("AnyOrigin"); – user10863293 Apr 09 '19 at 10:07