问题我在signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secret")), SecurityAlgorithms.HmacSha256)
使用TokenController
时,我500 Internal Server Error
获得var encoded_token = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler().WriteToken(token);
。
我认为这可能与适当的证书有关。
当我删除该行并转到http://localhost:61571/api/Users
时,我会收到401 Unauthorized
状态代码。当我将其插入在线解码器时,创建的JWT似乎工作正常。
所以我的问题是:
JwtSecurityTokenHandler().WriteToken(token);
给我500个内部服务器错误?我使用VS2017和ASP.NET Core 1.1。这一切都在VS2017中的IIS Express上运行。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using ToDoApi.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System;
namespace ToDoApi
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ToDoApi.Data.ApplicationDbContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton<IUserService, UserService>();
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
env.EnvironmentName = EnvironmentName.Development;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}
var keyAsBytes = Encoding.ASCII.GetBytes("secret");
var options = new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secret")),
ValidateIssuerSigningKey = true,
ValidAudience = "http://localhost:61571",
ValidateAudience = true,
ValidIssuer = "http://localhost:61571",
ValidateIssuer = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
}
};
app.UseJwtBearerAuthentication(options);
app.UseMvc();
}
}
}
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using ToDoApi.Models;
namespace ToDoApi.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
public class TokenController : Controller
{
[HttpPost]
public IActionResult Token([FromBody] User model)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var user = new User { ID = 1, Username = "username", Password = "password" };//await _userManager.FindByNameAsync(model.Email);
//if (user == null || _passwordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) != PasswordVerificationResult.Success)
//{
// return BadRequest();
// }
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, "username"),
new Claim(JwtRegisteredClaimNames.Jti, "40fdb6d4-1ea5-49af-9fcc-edb9e8d18dd5"),
new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.UtcNow).ToUniversalTime().ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
};
var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(
issuer: "http://localhost:61571",
audience: "http://localhost:61571",
claims: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(10),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secret")), SecurityAlgorithms.HmacSha256)
);
var encoded_token = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler().WriteToken(token);
return Ok(new
{
token = encoded_token,
expiration = token.ValidTo
});
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ToDoApi.Models;
using ToDoApi.Services;
using Microsoft.AspNetCore.Authorization;
using System.IdentityModel.Tokens.Jwt;
namespace ToDoApi.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
public class UsersController : Controller
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
// GET: api/Users
[Authorize]
[HttpGet]
public IEnumerable<User> GetUsers()
{
return _userService.ListAll();
}
}
}
答案 0 :(得分:0)
您获得500代码的原因可能是您使用HMACSHA256
的密钥太短。尝试使用至少128位大小的字符串(16个符号)。
对于它所依赖的401代码。如果在尝试生成令牌时遇到500错误,那么您在Authorization标头中使用了哪个令牌?
401的另一个棘手原因可能是您正在使用Bearer
授权以及Cookie和Identity Framework。在这种情况下,您需要在UseJwtBearerAuthentication
之前致电UseIdentity
。但是从您提供的代码示例中,您似乎不使用Identity。