title: Core 2.0 API Auth with JWT returns unauthorized
body: <p>I'm trying to add Token Authentication with JWT to my .Net Core 2.0 app.  I have a simple controller that returns a list of users for testing.  </p>
  
  <pre><code>[Authorize]
  [Route("api/[controller]")]
  public class UsersController : Controller
  {
      ...
  
      [HttpGet]
      [Route("api/Users/GetUsers")]
      public IEnumerable&lt;ApplicationUser&gt; GetUsers()
      {
          return _userManager.Users;
      }
  
  
  }
  </code></pre>
  
  <p>I have an API Controller for Token security.  It has a login method which returns a Token string result.</p>
  
  <pre><code>    [HttpPost(nameof(Login))]
      public async Task&lt;IActionResult&gt; Login([FromBody] LoginResource resource)
      {
          if (resource == null)
              return BadRequest("Login resource must be asssigned");
  
          var user = await _userManager.FindByEmailAsync(resource.Email);
  
          if (user == null || (!(await _signInManager.PasswordSignInAsync(user, resource.Password, false, false)).Succeeded))
              return BadRequest("Invalid credentials");
  
          string result = GenerateToken(user.UserName, resource.Email);
  
          // Token is created, we can sign out
          await _signInManager.SignOutAsync();
  
          return Ok(result);
      }
  
      private string GenerateToken(string username, string email)
      {
          var claims = new Claim[]
          {
              new Claim(ClaimTypes.Name, username),
              new Claim(ClaimTypes.Email, email),
              new Claim(JwtRegisteredClaimNames.Nbf, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()),
              new Claim(JwtRegisteredClaimNames.Exp, new DateTimeOffset(DateTime.Now.AddDays(1)).ToUnixTimeSeconds().ToString()),
          };
  
          var token = new JwtSecurityToken(
              new JwtHeader(new SigningCredentials(
                  new SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
                                           SecurityAlgorithms.HmacSha256)),
              new JwtPayload(claims));
  
          return new JwtSecurityTokenHandler().WriteToken(token);
      }
  </code></pre>
  
  <p>I have a small console app just for testing the API.  When I attempt to Get the Users using the jwt.  I receive an immediate "unauthorized".  If I remove the "[Authorize]" from the users Controller... success.  It appears that my header Authorization is not recognized, but not sure why.  </p>
  
  <pre><code>    private static async Task&lt;String&gt; GetUsers(String jwt)
      {
          var url = "https://localhost:44300/";
          var apiUrl = $"/api/Users/";
  
          using (var client = new HttpClient() { BaseAddress = new Uri(url) })
          {
              client.BaseAddress = new Uri(url);
              client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
              client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");
  
              using (var response = await client.GetAsync(apiUrl))
              {
                  if (response.StatusCode == System.Net.HttpStatusCode.OK)
                      return await response.Content.ReadAsStringAsync();
  
                  else return null;
              }
          }
      }
  </code></pre>
  
  <p>I'm basing my attempts on the article <a href="https://www.codeproject.com/Articles/1203975/JWT-Security-Part-Create-Token" rel="nofollow noreferrer">here</a>  ... some of which might be slightly out of date.   </p>
  
  <p><strong>Update - Excerpt of Startup.cs</strong></p>
  
  <pre><code>        services.AddAuthentication(options =&gt;
          {
              options.DefaultAuthenticateScheme = "Jwt";
              options.DefaultChallengeScheme = "Jwt";
          }).AddJwtBearer("Jwt", options =&gt;
          {
              options.TokenValidationParameters = new TokenValidationParameters
              {
                  ValidateAudience = false,
                  //ValidAudience = "the audience you want to validate",
                  ValidateIssuer = false,
                  //ValidIssuer = "the isser you want to validate",
  
                  ValidateIssuerSigningKey = true,
                  IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
  
                  ValidateLifetime = true, //validate the expiration and not before values in the token
  
                  ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
              };
          });
  </code></pre>
  
  <p><strong>Configure...</strong> </p>
  
  <pre><code>    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
          if (env.IsDevelopment())
          {
              app.UseBrowserLink();
              app.UseDeveloperExceptionPage();
              app.UseDatabaseErrorPage();
          }
          else
          {
              app.UseExceptionHandler("/Home/Error");
          }
  
          app.UseStaticFiles();
  
          app.UseAuthentication();
  
          app.UseMvc(routes =&gt;
          {
              routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}");
          });
  
          //app.UseJwtBearerAuthentication(
          //    new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions
          //    );
  
  
      }
  </code></pre>
  
  <p><strong>Solution:</strong>  </p>
  
  <p>This line was escaping the token therefore causing it to be invalid when passed in the next request:</p>
  
  <pre><code>var result = await response.Content.ReadAsStringAsync();
  </code></pre>
  
  <p>Replaced with:</p>
  
  <pre><code>var result = await response.Content.ReadAsAsync&lt;string&gt;();
  </code></pre>
  
  <p>Note:  To use this ext method I had to "install-package Microsoft.AspNet.WebApi.Client"</p>