Как настроить аутентификацию jwt с помощью TimeProvider в тестировании интеграции .NET 9 - Проверка токена не удастся с C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как настроить аутентификацию jwt с помощью TimeProvider в тестировании интеграции .NET 9 - Проверка токена не удастся с

Сообщение Anonymous »

Мое приложение - веб -API ASP.net Core 9. Я настраиваю аутентификацию с помощью этого метода расширения: < /p>

Код: Выделить всё

public static void SetupAuthentication(this IServiceCollection services)
{
var authSettings = services.BuildServiceProvider().GetService()?.Value;

// JWT Configuration
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = authSettings!.Jwt.Issuer,
ValidAudience = authSettings!.Jwt.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authSettings!.Jwt.Secret)),
ClockSkew = TimeSpan.Zero,
};
})
.AddGoogle(options =>
{
options.ClientId = authSettings!.Google.ClientId;
options.ClientSecret = authSettings!.Google.ClientSecret;
});
}
в другом месте я регистрирую timeprovider с

Код: Выделить всё

public static void RegisterServices(this IServiceCollection services)
{
services.AddScoped();

// used for time manipulation and testing
// we should use this instead of DateTime.Now
services.TryAddSingleton(TimeProvider.System);
}
Я использую метод в TokenService для создания JWT, которые можно использовать для доступа к API. Этот метод обычно выглядит так: < /p>

Код: Выделить всё

public AccessTokenResponse CreateAccessToken(ApplicationUser user, string[] roles)
{
List claims =
[
new(JwtRegisteredClaimNames.Sub, user.Id),
new(JwtRegisteredClaimNames.Email, user.Email!),
new(JwtRegisteredClaimNames.EmailVerified, user.EmailConfirmed.ToString()),
];

claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));

var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Secret));
var credentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha512Signature);
var expiresAt = DateTime.UtcNow.AddMinutes(_jwtSettings.ExpiryInMinutes);

var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = expiresAt,
SigningCredentials = credentials,
Issuer = _jwtSettings.Issuer,
Audience = _jwtSettings.Audience,
};

var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);

return new AccessTokenResponse(tokenHandler.WriteToken(token), expiresAt);
}
Но теперь я хочу использовать TimeProvider , чтобы я мог проверить истечение срока действия токена плюс некоторые. Поэтому я обновил метод, теперь он выглядит так: < /p>

Код: Выделить всё

public AccessTokenResponse CreateAccessToken(ApplicationUser user, string[] roles)
{
List claims =
[
new(JwtRegisteredClaimNames.Sub, user.Id),
new(JwtRegisteredClaimNames.Email, user.Email!),
new(JwtRegisteredClaimNames.EmailVerified, user.EmailConfirmed.ToString()),
];

claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));

var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Secret));
var credentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha512Signature);

var now = timeProvider.GetUtcNow();
var expiresAt = now.DateTime.AddMinutes(_jwtSettings.ExpiryInMinutes);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = expiresAt,
SigningCredentials = credentials,
Issuer = _jwtSettings.Issuer,
Audience = _jwtSettings.Audience,
NotBefore = now.DateTime,
IssuedAt = now.DateTime,
};

var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return new AccessTokenResponse(tokenHandler.WriteToken(token), expiresAt);
}
Конечно, TimeProvider вводится в службу для разрешения DI Container. Теперь, когда я запускаю свои тесты, я получаю эту ошибку: < /p>

nmicrosoft.aspnetcore.authentication.jwtbearer.jwtbearerHandler]BR />
Bearer не был завершен. Отказ от неудачи: IDX10223: Проверка пожизненной проверки не удалась. Токен истек. Validto (UTC): '12/31/1999 11:15:00 вечера ', текущее время (UTC):' 40.04.2025 3:06:23 PM '. '01/01/20000 00:15:00 'Должно быть, после этого: '30/04/2025 08:08:05

Код: Выделить всё

1 audiences, Nullable
1, прежде чем, нулевой

Код: Выделить всё

1 expires, Nullable
1 issuedat)

Я попытался настроить TimeProvider в моей конфигурации аутентификации - без повезло. Я попытался установить значение для nowbefore и issuedat в SecurityTokendescriptor -без удачи.
Для справки, вот CustomWeBApplicationFactory , где я регистрирую faketimeprovider :
:
:
public class CustomWebApplicationFactory : WebApplicationFactory, IAsyncLifetime
{
public readonly FakeTimeProvider FakeTimeProvider = new();

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(services =>
{
var timeProviderDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(TimeProvider));
if (timeProviderDescriptor != null)
{
services.Remove(timeProviderDescriptor);
services.AddSingleton(FakeTimeProvider);
}
});
}
}

Я также пробовал инициализацию faketimeprovider с определенной датой - не повезло. Я делаю что -то не так? Есть ли конкретный способ настроить TimeProvider в интеграционных тестах?>

Подробнее здесь: https://stackoverflow.com/questions/796 ... tion-tests
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»