![](/img/trans.png)
[英]How to manually validate JWT based on username in the url asp.net core
[英]How Do I Manually Validate a JWT Asp.Net Core?
那里有數以百萬計的指南,但似乎沒有一個能滿足我的需求。 我正在創建一個身份驗證服務器,它只需要發布和驗證/重新發布令牌。 所以我不能創建一個中間件類來“驗證”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
}
上面的這一大塊代碼將Deserialize
CredentialUser
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
}
}
我主要從 ASP.Net Core 源代碼中
竊取了
這段代碼: https : //github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs#L45
從那個代碼我創建了這個函數:
private string Authenticate(string token) {
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
List<Exception> validationFailures = null;
SecurityToken validatedToken;
var validator = new JwtSecurityTokenHandler();
// These need to match the values used to generate the token
TokenValidationParameters validationParameters = new TokenValidationParameters();
validationParameters.ValidIssuer = "http://localhost:5000";
validationParameters.ValidAudience = "http://localhost:5000";
validationParameters.IssuerSigningKey = key;
validationParameters.ValidateIssuerSigningKey = true;
validationParameters.ValidateAudience = true;
if (validator.CanReadToken(token))
{
ClaimsPrincipal principal;
try
{
// This line throws if invalid
principal = validator.ValidateToken(token, validationParameters, out validatedToken);
// If we got here then the token is valid
if (principal.HasClaim(c => c.Type == ClaimTypes.Email))
{
return principal.Claims.Where(c => c.Type == ClaimTypes.Email).First().Value;
}
}
catch (Exception e)
{
_logger.LogError(null, e);
}
}
return String.Empty;
}
validationParameters
需要與您的GenerateToken
函數中的那些匹配,然后它應該可以很好地驗證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.