В то время как ASOS намеренно мешает вам создавать токены из произвольных мест (они могут генерироваться только во время запросов OpenID Connect), вы можете напрямую использовать базовые API-интерфейсы ASP.NET для генерации поддельных токенов, которые будут приняты валидацией OAuth2 промежуточный слой:
var provider = container.GetRequiredService<IDataProtectionProvider>();
var protector = provider.CreateProtector(
nameof(OpenIdConnectServerMiddleware),
OpenIdConnectServerDefaults.AuthenticationScheme, "Access_Token", "v1");
var format = new TicketDataFormat(protector);
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, "Bob le Bricoleur"));
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
OpenIdConnectServerDefaults.AuthenticationScheme);
var token = format.Protect(ticket);
Тем не менее, это редко наиболее эффективный метод, если вы хотите проверить свой собственный API, токены защищенных. Вместо этого я бы рекомендовал установить HttpContext.User
или использовать события промежуточного программного обеспечения проверки OAuth2 для использования поддельных идентификаторов без задействования криптографических операций.
Вы также можете дразнить AccessTokenFormat
:
[Fact]
public async Task ValidTokenAllowsSuccessfulAuthentication()
{
// Arrange
var server = CreateResourceServer();
var client = server.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, "/");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "valid-token");
// Act
var response = await client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Fabrikam", await response.Content.ReadAsStringAsync());
}
private static TestServer CreateResourceServer(Action<OAuthValidationOptions> configuration = null)
{
var builder = new WebHostBuilder();
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(MockBehavior.Strict);
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "invalid-token")))
.Returns(value: null);
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "valid-token")))
.Returns(delegate
{
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties();
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
builder.ConfigureServices(services =>
{
services.AddAuthentication();
});
builder.Configure(app =>
{
app.UseOAuthValidation(options =>
{
options.AccessTokenFormat = format.Object;
// Run the configuration delegate
// registered by the unit tests.
configuration?.Invoke(options);
});
// Add the middleware you want to test here.
app.Run(context =>
{
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
{
return context.Authentication.ChallengeAsync();
}
var identifier = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
return context.Response.WriteAsync(identifier);
});
});
return new TestServer(builder);
}
Мне нравится последний подход, но это только кажется, работать до тех пор, как я не добавить UseStartup() строителю (только получил .well известный недоступная ошибка и неавторизованная, если я закомментирую все токены auth при запуске). –
Baserz
Средство проверки достоверности OAuth2 не использует обнаружение (в отличие от промежуточного программного обеспечения для проводника JWT), поэтому, скорее всего, это не проблема. – Pinpoint
Я использую UseJwtBearerAuthentication в сочетании с UseOpenIdConnectServer в своем приложении (я использую токены jwt), но я все же пробовал его с этими комментариями. Выполните некоторую отладку и посмотрите, что вызывает ее. – Baserz