【发布时间】:2017-12-02 04:34:48
【问题描述】:
那里有数以百万计的指南,但似乎没有一个能满足我的需求。我正在创建一个身份验证服务器,它只需要发布和验证/重新发布令牌。所以我不能创建一个中间件类来“验证”cookie 或标头。我只是收到字符串的 POST,我需要以这种方式验证令牌,而不是 .net 核心提供的 Authorize 中间件。
我的初创公司包含我可以开始工作的唯一令牌发行者示例。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
var secretKey = "mysupersecret_secretkey!123";
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
var options = new TokenProviderOptions
{
// The signing key must match!
Audience = "AllApplications",
SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
Issuer = "Authentication"
};
app.UseMiddleware<TokenProviderMiddleware>(Microsoft.Extensions.Options.Options.Create(options));
我可以在创建时使用中间件,因为我只需要截取用户名和密码的正文。中间件从前面的Startup.cs 代码中获取选项,检查请求路径并从下面看到的上下文中生成令牌。
private async Task GenerateToken(HttpContext context)
{
CredentialUser usr = new CredentialUser();
using (var bodyReader = new StreamReader(context.Request.Body))
{
string body = await bodyReader.ReadToEndAsync();
usr = JsonConvert.DeserializeObject<CredentialUser>(body);
}
///get user from Credentials put it in user variable. If null send bad request
var now = DateTime.UtcNow;
// Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
// You can add other claims here, if you want:
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, JsonConvert.SerializeObject(user)),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, now.ToString(), ClaimValueTypes.Integer64)
};
// Create the JWT and write it to a string
var jwt = new JwtSecurityToken(
issuer: _options.Issuer,
audience: _options.Audience,
claims: claims,
notBefore: now,
expires: now.Add(_options.Expiration),
signingCredentials: _options.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
///fill response with jwt
}
上面的这个大块代码将DeserializeCredentialUser json ,然后执行一个返回用户对象的存储过程。然后,我将添加三个声明,然后将其寄回。
我能够成功生成 jwt,并使用 jwt.io 之类的在线工具,我输入了密钥,该工具说它是有效的,并带有一个我可以使用的对象
{
"sub": " {User_Object_Here} ",
"jti": "96914b3b-74e2-4a68-a248-989f7d126bb1",
"iat": "6/28/2017 4:48:15 PM",
"nbf": 1498668495,
"exp": 1498668795,
"iss": "Authentication",
"aud": "AllApplications"
}
我遇到的问题是了解如何根据签名手动检查声明。因为这是一个发布和验证令牌的服务器。像大多数指南一样,设置Authorize 中间件不是一种选择。下面我正在尝试验证令牌。
[Route("api/[controller]")]
public class ValidateController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Validate(string token)
{
var validationParameters = new TokenProviderOptions()
{
Audience = "AllMyApplications",
SigningCredentials = new
SigningCredentials("mysupersecret_secretkey!123",
SecurityAlgorithms.HmacSha256),
Issuer = "Authentication"
};
var decodedJwt = new JwtSecurityTokenHandler().ReadJwtToken(token);
var valid = new JwtSecurityTokenHandler().ValidateToken(token, //The problem is here
/// I need to be able to pass in the .net TokenValidParameters, even though
/// I have a unique jwt that is TokenProviderOptions. I also don't know how to get my user object out of my claims
}
}
【问题讨论】:
标签: c# asp.net-core jwt