I've seen similar threads to this issue, but I had no luck solving it. LogIn worked successfuly but when I try to GET data of the user loggedIn in my home page I receive this error 401 Unauthorized the same erroe is showen also in Postman
My startup.cs
public class Startup
{
private string _connectionString=null;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Inject AppSettings
services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
_connectionString = Configuration["secretConnectionstring"];
//without this it will define for example id to Id
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options => {
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
(resolver as DefaultContractResolver).NamingStrategy = null;
});
services.AddEntityFrameworkNpgsql()
.AddDbContext<ApiContext>(
opt => opt.UseNpgsql(_connectionString));
services.AddEntityFrameworkNpgsql()
.AddDbContext<AuthentificationContext>(
options => options.UseNpgsql(_connectionString));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<AuthentificationContext>();
services.Configure<IdentityOptions>(options => {
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 4;
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Jwt Authentification
var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x=> {
x.RequireHttpsMetadata = false;
x.SaveToken = false;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
services.AddTransient<dataSeed>();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, dataSeed seed)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
app.UseAuthentication();
}
}
}
UserprofileController
{
[Route("api/[controller]")]
[ApiController]
public class UserProfileController : ControllerBase
{
private UserManager<ApplicationUser> _userManager;
public UserProfileController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
[HttpGet]
[Authorize]
//GET : /api/UserProfile
public async Task<Object> GetUserProfile()
{
string userId = User.Claims.First(c => c.Type == "UserID").Value;
var user = await _userManager.FindByIdAsync(userId);
return new
{
user.fullName,
user.Email,
user.UserName
};
}
}
}
UserServices
headers = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json'
})
}
readonly BaseUrl = 'http://localhost:53847/api';
constructor(private fb: FormBuilder, private http: HttpClient) { }
formModel = this.fb.group({
UserName: ['', Validators.required],
Email: ['', Validators.email],
fullName: ['', Validators.required],
Passwords: this.fb.group({
Password: ['',[Validators.required, Validators.minLength(4)]],
ConfirmPassword: ['', Validators.required],
}, { validator : this.comparePasswords})
});
comparePasswords(fb: FormGroup) {
let confirmPswdCtrl = fb.get('ConfirmPassword');
//passowrdMismatch
//confirmPswdCtrl.errors={passowrdMismatch:true}
if (confirmPswdCtrl.errors == null || 'passowrdMismatch' in confirmPswdCtrl.errors) {
if (fb.get('Password').value != confirmPswdCtrl.value)
confirmPswdCtrl.setErrors({ passowrdMismatch: true });
else
confirmPswdCtrl.setErrors(null);
}
}
register() {
var body = {
UserName: this.formModel.value.UserName,
Email: this.formModel.value.Email,
fullName: this.formModel.value.fullName,
Password: this.formModel.value.Passwords.Password,
};
return this.http.post(this.BaseUrl + '/ApplicationUser/Register', body, this.headers);
}
login(formData) {
return this.http.post(this.BaseUrl + '/ApplicationUser/Login', formData, this.headers);
}
getUserProfile() {
var tokenHeader = new HttpHeaders({ 'Authorization': 'Bearer' + localStorage.getItem('token'), 'Content-Type': 'application/json' });
return this.http.get(this.BaseUrl + '/UserProfile', { headers: tokenHeader });
}
}
ApplicationUserController the PostMethod
[HttpPost]
[Route("Login")]
//POST : /api/ApplicationUser/Login
public async Task<IActionResult> Login(LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("UserID",user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return Ok(new { token });
}
else
return BadRequest(new { message = "Username or password is incorrect." });
}
}
Help Plz .. Thx