0

I'm trying to create an authorize with jwt bearer, but I cant do it on my application, when I do with postman it happening what I want, but on my app don't...

Service.ts (Angular 8)

getAll(): Observable<...[]> {
    return this.httpClient.get<...[]>(environment.url + "api",
    { headers: {'Authorization' : 'Bearer ' + token });
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    var symetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"]));
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = symetricSecurityKey
            };
        });
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

AuthController.cs

[HttpPost]
[Route("login")]
public async Task<AccountModel> Login([FromBody] AccountModel model)
{

    if (ModelState.IsValid)
    {
        var user = new ApplicationUser();
        var signInResultado = new Microsoft.AspNetCore.Identity.SignInResult();

        Task.Run(async () =>
        {
            user = await _userManager.FindByEmailAsync(model.Email);
        }).Wait();

        Task.Run(async () =>
        {
            await _userManager.CheckPasswordAsync(user, model.Password);
        }).Wait();

        Task.Run(async () =>
        {
            signInResultado = await _signInManager.PasswordSignInAsync(
            user.UserName,
            model.Password,
            isPersistent: false,
            lockoutOnFailure: false);
        }).Wait();

        if (signInResultado.Succeeded)
        {
            var appUser = _userManager.Users.FirstOrDefault(u => u.Id == user.Id);
            var claims = await GetValidClaims(appUser);
            var accountModel = new AccountModel(user, _roleManager);

            accountModel.Token = GenerateJwtToken(appUser, claims);
            return accountModel;
        }

    }
    return model;
}
private string GenerateJwtToken(ApplicationUser user, List<Claim> claims)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_configuration["JwtKey"]);


    var tokens = new JwtSecurityToken(
        claims: claims,
        expires: DateTime.UtcNow.AddDays(1),
        signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        );

    return new JwtSecurityTokenHandler().WriteToken(tokens);

}
private async Task<List<Claim>> GetValidClaims(ApplicationUser user)
{
    IdentityOptions _options = new IdentityOptions();
    var claims = new List<Claim>
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
        new Claim(_options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
        new Claim(_options.ClaimsIdentity.UserNameClaimType, user.UserName)
    };
    var userClaims = await _userManager.GetClaimsAsync(user);
    var userRoles = await _userManager.GetRolesAsync(user);
    claims.AddRange(userClaims);
    foreach (var userRole in userRoles)
    {
        claims.Add(new Claim(ClaimTypes.Role, userRole));
        var role = await _roleManager.FindByNameAsync(userRole);
        if (role != null)
        {
            var roleClaims = await _roleManager.GetClaimsAsync(role);
            foreach (Claim roleClaim in roleClaims)
            {
                claims.Add(roleClaim);
            }
        }
    }
    return claims;
}

Any method with Role = Admin

[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult<IEnumerable<RoleModel>> Get()

Postman - Login (Create Token)

enter image description here

Postman - Get any method with Role = Admin

enter image description here

When I did on my application, it redirected to Identity/Account/Login

enter image description here enter image description here

LeoHenrique
  • 229
  • 5
  • 16
  • As you censored all urls: are they correct? In your Service.ts there is something missing after the api part. What is written to the log? – hyvte Aug 07 '19 at 14:39
  • it's all url correct, because if I remove the `[Authorize(Roles = "Admin")]` its work... where I can see the log? (console? if its, there is nothing written in the log) – LeoHenrique Aug 07 '19 at 14:46
  • Yeah when you are not running with IIS it's showing a console with logs. Authentication Middleware also writes its logs there – hyvte Aug 07 '19 at 14:47
  • But where, at chrome console? there is nothing there – LeoHenrique Aug 07 '19 at 14:54
  • 1
    Not related but this monstrous `Task.Run( async () .... ).Wait()` looks horrible. Why would you wrap a typical async call with `Task.Run(...).Wait()`? – Wiktor Zychla Aug 07 '19 at 14:57
  • I work with a team @WiktorZychla and I can't change other people's code, told me to study and do JWT and that's what I'm doing... I didn't mean to be ignorant, sorry it seemed – LeoHenrique Aug 07 '19 at 15:03
  • Whoever wrote this code, ask them to double check that, refer to this discussion here. As for your problem, are you sure your header is here when called from the browser? – Wiktor Zychla Aug 07 '19 at 15:11
  • @LeoHenrique I don't find `signInResultado` variable is assigned any value after it is initialized. So may be `signInResultado.Succeeded` is false. Also, go to https://jwt.io/ and decode your token to ensure that claims are added to JWT token – Mohsin Mehmood Aug 07 '19 at 15:46
  • @MohsinMehmood, I updated the post with the entire login method... I already decode with jwt.io and I have the claims that I need... – LeoHenrique Aug 07 '19 at 16:12
  • @WiktorZychla, I don't know if that anwsers you question, but when I create a policy (my first test), I can enter on method with Authorize(Policy = "Policy"), so if that information is sent with token too, so I think that I have the token on header – LeoHenrique Aug 07 '19 at 16:15
  • @LeoHenrique Have you confirmed that `Authorization` header is set when call is initiated from Angular app to `/api` end point? Verify in Request headers – Mohsin Mehmood Aug 07 '19 at 16:32
  • @MohsinMehmood I updated the post with request header – LeoHenrique Aug 07 '19 at 17:37
  • I took the token by the request header and tested it on the postman and it worked, but coming from angular doesn't work – LeoHenrique Aug 07 '19 at 17:54
  • guys, I was able to do with this link: https://stackoverflow.com/a/47025009/10647645 ... Thank you very much – LeoHenrique Aug 07 '19 at 18:56

0 Answers0