Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I resolve 401 unauthorized in angular?

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

like image 592
user10863293 Avatar asked Apr 09 '19 09:04

user10863293


1 Answers

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)
    {
like image 189
H20rider Avatar answered Mar 29 '23 23:03

H20rider