'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 :
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
Solution 1:[1]
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.
Solution 2:[2]
You need configure CORS for your Web API.
Refer link https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2 and link How to enable CORS in ASP.NET Core
Solution 3:[3]
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)
{
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mbojko |
Solution 2 | Hien Nguyen |
Solution 3 |