我想保护我的API端点,以便它只能通过身份验证进行访问,最后我得到了这个错误。我使用register方法注册用户并获取令牌。然后,我使用请求头中的长令牌访问受保护的区域。但我一直得到401授权错误。到底怎么回事!
http Get http://localhost:5000/Account/Protected 'authorization:Bearer eyJhb....fx0IM'
HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Fri, 27 Jul 2018 12:36:46 GMT
Server: Kestrel
WWW-Authenticate: Bearer error="invalid_token", error_description="The token as no expiration"
我有这个控制器配置用于
Account Controller
. 注册方法很好地工作并且注册了这个人,现在如果我想用受保护的控制器添加一个测试API。我得到401错误。
namespace Lemon.Auth.Controllers
{
[Route("[controller]/[action]")]
public class AccountController : ControllerBase
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration;
public AccountController(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IConfiguration configuration
)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
}
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)
[HttpGet]
public async Task<object> Protected()
{
return "Protected area";
}
// Handlers
[HttpPost]
public async Task<object> Login([FromBody] LoginDto model)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
if(result.Succeeded)
{
var appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);
return await GenerateJwtToken(model.Email, appUser);
}
throw new ApplicationException("Invalid Login Attempt");
}
// Handler :Register:
public async Task<object> Register([FromBody] RegisterDto model)
{
var user = new IdentityUser
{
UserName = model.Email,
Email = model.Email
};
// debuggi
try
{
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, false);
return await GenerateJwtToken(model.Email, user);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
}
throw new ApplicationException("Unknown Error");
}
private async Task<object> GenerateJwtToken(string email, IdentityUser user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpiresDays"]));
Console.WriteLine("hello");
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
}
这是我的初创公司.cs
public void ConfigureServices(IServiceCollection services)
{
// Db and context
services.AddEntityFrameworkNpgsql().AddDbContext<ApplicationDbContext>(options =>
{
options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"));
}
);
// add Identity
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// add jwt
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // clear default behaviour
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero // remove delay of token when expire
};
});
// add mvc
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext dbContext)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
// app.UseHttpsRedirection();
app.UseMvc();
app.UseAuthentication();
// ensure tables are created
dbContext.Database.EnsureCreated();
}
我要做的就是保护API。我参考了这个教程
https://medium.com/@ozgurgul/asp-net-core-2-0-webapi-jwt-authentication-with-identity-mysql-3698eeba6ff8