我正在编写一个使用ASP.NET核心作为后端/服务和Angular2作为前端的Web应用程序,并使用带有身份验证/授权的麻烦。
在ASP.NET核心中,我只有一个html页面和控制器,带有索引的HomeController允许匿名访问([AllowAnonymous])。此单页面为客户提供angular2-app。
所有其他通信都使用ApiControllers(在ASP.NET核心中只是普通的控制器,但这些控制器上的操作期望并发送JSON数据。对于身份验证/授权,我想使用jwt令牌。用户,角色,声明等。使用EF核心存储在IdentityDbContext中。
我发现的大多数教程都已过时,不完整或引用第三方OAuth解决方案。我不是在寻找OAuth,我只是想要一个带有用户名/密码的页面并使用令牌保持登录,因为我正在使用所有API来获取后端来回的数据。 我阅读了很多教程,尝试了一些有用的库,但仍然对如何为基于令牌的安全性设置中间件链感到困惑。据我所知,我需要添加身份服务,因为我想使用IdentityDbContext:
public void ConfigureServices(IServiceCollection services)
{
[...]
services.AddIdentity<IdentityUserEntity, IdentityRoleEntity>()
.AddEntityFrameworkStores<ApplicationDbContext, long>()
.AddDefaultTokenProviders();
[...]
}
但是我需要在Configure中设置哪些中间件?我需要app.UseIdentity()还是app.UseJwtBearerAuthentication(o)?在JwtBearer检查Tokens ??
之前,不会使用UseIdentity快捷方式进行身份验证public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
[...]
app.UseIdentity();
[...]
app.UseJwtBearerAuthentication(jwtOptions);
[...]
}
我问,因为客户端在我的TokenController之后自动进行了身份验证,我执行了对_signInManager.PasswordSignInAsync(...)的调用,即使我的客户端从未收到过jwt。所以ASP.NET身份管理在某种程度上找到了一些在登录后识别我的用户的方法,这当然不应该发生。
// simplified controller
public class TokenController : Controller
{
[HttpPost("[action]")]
[AllowAnonymous]
public async Task<JsonResult> Login([FromBody]LoginViewModel loginRequest)
{
var signin = await _signInManager.PasswordSignInAsync(loginRequest.Username, loginRequest.Passwort, true, true);
}
// this will work even though I don't handle any Tokens in the Client yet, so some other authentication mechanism is at work:
[HttpGet("test")]
[Authorize]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
那么如何实现基于令牌的身份验证以及其他?
[UPDATE]
我猜我需要拦截Cookie身份验证事件并拒绝主体来禁用Cookie身份验证(请参阅https://stackoverflow.com/a/38893778/7021): 但由于某种原因,我的事件处理程序永远不会被调用。
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ValidateAsync
}
});
public static async Task ValidateAsync(CookieValidatePrincipalContext context)
{
context.RejectPrincipal();
await context.HttpContext.Authentication.SignOutAsync("BsCookie");
}
关于身份验证,Cookie和令牌的更多好读物:
- http://andrewlock.net/exploring-the-cookieauthenticationmiddleware-in-asp-net-core/
- https://stormpath.com/blog/token-authentication-asp-net-core
答案 0 :(得分:3)
MS提供了基于jwt令牌的基本身份验证库,您可以在此处查看如何使用它:
https://code.msdn.microsoft.com/How-to-achieve-a-bearer-9448db57
在startup.cs中,首先配置Jwt Beare
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = TokenAuthOption.Key,
ValidAudience = TokenAuthOption.Audience,
ValidIssuer = TokenAuthOption.Issuer,
// When receiving a token, check that we've signed it.
ValidateIssuerSigningKey = true,
// When receiving a token, check that it is still valid.
ValidateLifetime = true,
// This defines the maximum allowable clock skew - i.e. provides a tolerance on the token expiry time
// when validating the lifetime. As we're creating the tokens locally and validating them on the same
// machines which should have synchronised time, this can be set to zero. Where external tokens are
// used, some leeway here could be useful.
ClockSkew = TimeSpan.FromMinutes(0)
}
});
现在您可以添加到服务
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
最后,在控制器中使用它,只需添加[授权(&#34; Bearer&#34;)]
[Route("api/[controller]")]
public class ValuesController : Controller
{
[HttpGet("GetStaff")]
[Authorize("Bearer")]
public IActionResult GetStaff()
{
List<string> model = new List<string>();
foreach (User user in UserStorage.Users ){
model.Add(user.Username);
}
return Json(model);
}
}