1

Im реализующего Aspnet OpenIdConnect Server (ASOS) в ядре 1.1 проекта в asp.net и им в настоящее время пытается реализовать некоторое интеграционное тестирование (xunit & moq) с помощью Microsoft.AspNetCore.TestHost.TestServer.Руководство поколения с использованием OpenIdConnect маркера доступа сервера (ASOS)

Вопрос, который у меня есть, представляет собой создание фальшивого accesstoken, с помощью которого можно заполнить AuthenticationHeaderValue для запросов HttpClient. Искал для этого рабочее решение, но sofar ive не увенчались успехом.

Итак, мой вопрос: У кого-нибудь есть вопрос, как вручную генерировать accesstokens для TestServer без необходимости вызывать конечную точку маркера ASOS для тестирования?

ответ

1

В то время как 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); 
} 
+0

Мне нравится последний подход, но это только кажется, работать до тех пор, как я не добавить UseStartup () строителю (только получил .well известный недоступная ошибка и неавторизованная, если я закомментирую все токены auth при запуске). – Baserz

+0

Средство проверки достоверности OAuth2 не использует обнаружение (в отличие от промежуточного программного обеспечения для проводника JWT), поэтому, скорее всего, это не проблема. – Pinpoint

+0

Я использую UseJwtBearerAuthentication в сочетании с UseOpenIdConnectServer в своем приложении (я использую токены jwt), но я все же пробовал его с этими комментариями. Выполните некоторую отладку и посмотрите, что вызывает ее. – Baserz