Mic*_*per 79 c# jwt .net-core jose
我一直在冒险让JWT在DotNet核心2.0上工作(现在到达最终版本).有大量的文档,但是所有的示例代码似乎都在使用已弃用的API并且刚刚进入Core,它确实令人眼花缭乱地想出它应该如何实现.我尝试使用Jose,但应用程序.不推荐使用UseJwtBearerAuthentication,并且没有关于下一步操作的文档.
有没有人有一个使用dotnet core 2.0的开源项目,它可以简单地从授权头解析JWT并允许我授权HS256编码的JWT令牌?
类下面不抛出任何异常,但没有请求授权,和我没有得到任何指示,为什么他们是未经授权的.响应是空的401,所以对我来说,表明没有异常,但秘密不匹配.
奇怪的是我的令牌是用HS256算法加密的,但是我没有看到任何指示器要求它强制它在任何地方使用该算法.
这是我到目前为止的课程:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace Site.Authorization
{
public static class SiteAuthorizationExtensions
{
public static IServiceCollection AddSiteAuthorization(this IServiceCollection services)
{
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("SECRET_KEY"));
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKeys = new List<SecurityKey>{ signingKey },
// Validate the token expiry
ValidateLifetime = true,
};
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.IncludeErrorDetails = true;
o.TokenValidationParameters = tokenValidationParameters;
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 401;
c.Response.ContentType = "text/plain";
return c.Response.WriteAsync(c.Exception.ToString());
}
};
});
return services;
}
}
}
Run Code Online (Sandbox Code Playgroud)
ale*_*rya 84
这是一个带有控制器的完整工作最小样本.我希望你可以使用Postman或JavaScript调用来检查它.
appsettings.json,appsettings.Development.json.添加一个部分.注意,Key应该相当长,Issuer是服务的地址:
...
,"Tokens": {
"Key": "Rather_very_long_key",
"Issuer": "http://localhost:56268/"
}
...
Run Code Online (Sandbox Code Playgroud)
!在实际项目中,不要将key保存在appsettings.json文件中.它应保存在Environment变量中,并按如下所示:
Environment.GetEnvironmentVariable("JWT_KEY");
Run Code Online (Sandbox Code Playgroud)更新:了解.net核心设置如何工作,您不需要完全从环境中获取它.你可以使用设置.但是,我们可能会将此变量写入生产中的环境变量,然后我们的代码将更喜欢环境变量而不是配置.
AuthRequest.cs:Dto保留传递登录名和密码的值:
public class AuthRequest
{
public string UserName { get; set; }
public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)在app.UseMvc()之前的Configure()方法中的Startup.cs:
app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)ConfigureServices()中的Startup.cs:
services.AddAuthentication()
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});
Run Code Online (Sandbox Code Playgroud)添加控制器:
[Route("api/[controller]")]
public class TokenController : Controller
{
private readonly IConfiguration _config;
private readonly IUserManager _userManager;
public TokenController(IConfiguration configuration, IUserManager userManager)
{
_config = configuration;
_userManager = userManager;
}
[HttpPost("")]
[AllowAnonymous]
public IActionResult Login([FromBody] AuthRequest authUserRequest)
{
var user = _userManager.FindByEmail(model.UserName);
if (user != null)
{
var checkPwd = _signInManager.CheckPasswordSignIn(user, model.authUserRequest);
if (checkPwd)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, user.Id.ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_config["Tokens:Issuer"],
_config["Tokens:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
}
}
return BadRequest("Could not create token");
}}
Run Code Online (Sandbox Code Playgroud)这就是所有人!干杯!
更新:人们问如何获得当前用户.去做:
在ConfigureServices()中的Startup.cs中添加
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)在控制器中添加到构造函数:
private readonly int _currentUser;
public MyController(IHttpContextAccessor httpContextAccessor)
{
_currentUser = httpContextAccessor.CurrentUser();
}
Run Code Online (Sandbox Code Playgroud)添加扩展名并在Controller中使用它(使用....)
public static class IHttpContextAccessorExtension
{
public static int CurrentUser(this IHttpContextAccessor httpContextAccessor)
{
var stringId = httpContextAccessor?.HttpContext?.User?.FindFirst(JwtRegisteredClaimNames.Jti)?.Value;
int.TryParse(stringId ?? "0", out int userId);
return userId;
}
}
Run Code Online (Sandbox Code Playgroud)Adr*_*zyk 17
我的tokenValidationParameters作品看起来像这样:
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = GetSignInKey(),
ValidateIssuer = true,
ValidIssuer = GetIssuer(),
ValidateAudience = true,
ValidAudience = GetAudience(),
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
Run Code Online (Sandbox Code Playgroud)
和
static private SymmetricSecurityKey GetSignInKey()
{
const string secretKey = "very_long_very_secret_secret";
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
return signingKey;
}
static private string GetIssuer()
{
return "issuer";
}
static private string GetAudience()
{
return "audience";
}
Run Code Online (Sandbox Code Playgroud)
此外,像这样添加options.RequireHttpsMetadata = false:
.AddJwtBearer(options =>
{
options.TokenValidationParameters =tokenValidationParameters
options.RequireHttpsMetadata = false;
});
Run Code Online (Sandbox Code Playgroud)
编辑:
别忘了打电话
app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)
在Startup.cs中 - > 在 app.UseMvc()之前配置方法;
这是一个适合您的解决方案.
在您的startup.cs中,首先将其配置为服务:
services.AddAuthentication().AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = "somethong",
ValidAudience = "something",
:
};
});
Run Code Online (Sandbox Code Playgroud)
第二,在config中调用此服务
app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)
现在您可以通过添加属性在控制器中使用它
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet]
public IActionResult GetUserInfo()
{
Run Code Online (Sandbox Code Playgroud)
有关使用angular作为Frond-end的完整详细信息源代码,请参阅此处
使用Web Api演示实现Asp.net Core 2.0 JWT承载令牌认证
添加包" Microsoft.AspNetCore.Authentication.JwtBearer "
Startup.cs ConfigureServices()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = "me",
ValidAudience = "you",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")) //Secret
};
});
Run Code Online (Sandbox Code Playgroud)
Startup.cs配置()
// ===== Use Authentication ======
app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)
User.cs //例如,它是一个模型类.它可以是任何东西.
public class User
{
public Int32 Id { get; set; }
public string Username { get; set; }
public string Country { get; set; }
public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
UserContext.cs //它只是上下文类.它可以是任何东西.
public class UserContext : DbContext
{
public UserContext(DbContextOptions<UserContext> options) : base(options)
{
this.Database.EnsureCreated();
}
public DbSet<User> Users { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
AccountController.cs
[Route("[controller]")]
public class AccountController : Controller
{
private readonly UserContext _context;
public AccountController(UserContext context)
{
_context = context;
}
[AllowAnonymous]
[Route("api/token")]
[HttpPost]
public async Task<IActionResult> Token([FromBody]User user)
{
if (!ModelState.IsValid) return BadRequest("Token failed to generate");
var userIdentified = _context.Users.FirstOrDefault(u => u.Username == user.Username);
if (userIdentified == null)
{
return Unauthorized();
}
user = userIdentified;
//Add Claims
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.UniqueName, "data"),
new Claim(JwtRegisteredClaimNames.Sub, "data"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")); //Secret
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken("me",
"you",
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return Ok(new
{
access_token = new JwtSecurityTokenHandler().WriteToken(token),
expires_in = DateTime.Now.AddMinutes(30),
token_type = "bearer"
});
}
}
Run Code Online (Sandbox Code Playgroud)
UserController.cs
[Authorize]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly UserContext _context;
public UserController(UserContext context)
{
_context = context;
if(_context.Users.Count() == 0 )
{
_context.Users.Add(new User { Id = 0, Username = "Abdul Hameed Abdul Sattar", Country = "Indian", Password = "123456" });
_context.SaveChanges();
}
}
[HttpGet("[action]")]
public IEnumerable<User> GetList()
{
return _context.Users.ToList();
}
[HttpGet("[action]/{id}", Name = "GetUser")]
public IActionResult GetById(long id)
{
var user = _context.Users.FirstOrDefault(u => u.Id == id);
if(user == null)
{
return NotFound();
}
return new ObjectResult(user);
}
[HttpPost("[action]")]
public IActionResult Create([FromBody] User user)
{
if(user == null)
{
return BadRequest();
}
_context.Users.Add(user);
_context.SaveChanges();
return CreatedAtRoute("GetUser", new { id = user.Id }, user);
}
[HttpPut("[action]/{id}")]
public IActionResult Update(long id, [FromBody] User user)
{
if (user == null)
{
return BadRequest();
}
var userIdentified = _context.Users.FirstOrDefault(u => u.Id == id);
if (userIdentified == null)
{
return NotFound();
}
userIdentified.Country = user.Country;
userIdentified.Username = user.Username;
_context.Users.Update(userIdentified);
_context.SaveChanges();
return new NoContentResult();
}
[HttpDelete("[action]/{id}")]
public IActionResult Delete(long id)
{
var user = _context.Users.FirstOrDefault(u => u.Id == id);
if (user == null)
{
return NotFound();
}
_context.Users.Remove(user);
_context.SaveChanges();
return new NoContentResult();
}
}
Run Code Online (Sandbox Code Playgroud)
在其他Web服务的Header中传递TokenType和AccessToken.

祝你好运!我只是初学者.我只用了一个星期就开始学习asp.net核心.
| 归档时间: |
|
| 查看次数: |
52617 次 |
| 最近记录: |