Я пытаюсь реализовать процесс аутентификации / авторизации, который при входе пользователя генерирует JWT и помещает его в файл cookie (при реализации я в основном использовал эту статью - думал, что это для .NET Core, а я использую .NET4.6: https://stormpath.com/blog/token-authentication-asp-net-core).Пока что этот процесс работает нормально, но когда я пытаюсь сделать запрос к защищенной конечной точке (украшенной атрибутом [Authorize]) с JWT в файле cookie, я всегда получаю 401 несанкционированный ответ.Несмотря на то, что JWT швы для проверки, и AuthenticationTicket возвращается из метода Unprotect класса CustomJwtDataFormat.
Как рекомендуется в ответе на этот вопрос Почему мой ClaimsIdentity IsAuthenticated всегда ложный (для веб-сайтовapi Authorize filter)? Я добавил параметр AuthenticationType при создании ClaimsIdentity.Но все тот же ответ 401.
Вот мой метод ConfigureAuth:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider(),
CookieName = "access_token",
AuthenticationMode =
Microsoft.Owin.Security.AuthenticationMode.Active,
AuthenticationType = AuthenticationTypes.Password,
TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
SettingsConfig.TokenValidationParameters)
});
}
Метод Unprotect класса CustomJwtDataFormat:
public AuthenticationTicket Unprotect(string protectedText)
{
var handler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = null;
SecurityToken validToken = null;
try
{
principal = handler.ValidateToken(protectedText, this.validationParameters, out validToken);
var validJwt = validToken as JwtSecurityToken;
if (validJwt == null)
{
throw new ArgumentException("Invalid JWT");
}
if (!validJwt.Header.Alg.Equals(algorithm, StringComparison.Ordinal))
{
throw new ArgumentException($"Algorithm must be '{algorithm}'");
}
}
catch (SecurityTokenValidationException e)
{
var ex = e;
return null;
}
catch (ArgumentException e)
{
var ex = e;
return null;
}
var identity = new ClaimsIdentity(principal.Identities.FirstOrDefault().Claims, AuthenticationTypes.Password);
// Validation passed. Return a valid AuthenticationTicket:
var authTicket = new AuthenticationTicket(identity, new AuthenticationProperties());
return authTicket;
My TokenValidationParameters:
public static TokenValidationParameters TokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = "ExampleIssuer",
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = "ExampleAudience",
// Validate the token expiry
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5)
};
Метод GenerateToken:
public static string GenerateToken(MetadataForToken tokenContentAndMetadata)
{
var symmetricKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenContentAndMetadata.SecretKey));
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(tokenContentAndMetadata.Claims),
Expires = now.AddMinutes(Convert.ToInt32(tokenContentAndMetadata.ExpireMinutes)),
SigningCredentials = new SigningCredentials(symmetricKey, tokenContentAndMetadata.SecurityAlgorithm),
Issuer = "ExampleIssuer",
Audience = "ExampleAudience"
};
var sToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(sToken);
return token;
}
Что я делаю не так?