0

У меня возникли проблемы с конкретной реализацией тестирования методов Web.API с помощью RestSharp. Я очень успешно выполнял POSTS и GETS в своих открытых (незащищенных) методах. Однако, когда мне нужно отправить токен, чтобы определить доступ, у меня проблемы.Как протестировать метод Web.API с передачей RestSharp в ClaimsPrincipal

Вот реализация:

Я использую Owin промежуточное программное обеспечение для моего Web.API. Клиент должен отправить в службу токенов, чтобы получить данный токен, содержащий свои претензии. Все это работает нормально.

В моем тесте мой Инициализатор имеет следующий код, который отправляет в службу токенов и возвращает токен. Это прекрасно работает - возвращается обратно маркер, как рекламируются:

[TestInitialize] 
    public void SetupTest() 
    { 

     _verificationErrors = new StringBuilder(); 

     _client = new RestClient 
     { 
      BaseUrl = new Uri(ConfigurationManager.AppSettings["ServicesBaseUrl"]) 
     }; 

     _serviceRequestPrepender = ConfigurationManager.AppSettings["ServiceRequestPrepender"]; 

     // Initialize this by getting the user token put back for all of the tests to use. 
     var request = new RestRequest(string.Format("{0}{1}", _serviceRequestPrepender, ConfigurationManager.AppSettings["TokenEndpointPath"]), Method.POST); 

     // Add header stuff 
     request.AddParameter("Content-Type", "application/x-www-form-urlencoded", ParameterType.HttpHeader); 
     request.AddParameter("Accept", "application/json", ParameterType.HttpHeader); 

     // Add request body 
     _userName = "{test student name}"; 
     _password = "{test student password}"; 
     _userGuid = "{this is a guid value!!}"; 

     _clientIdentifier = ConfigurationManager.AppSettings["ClientIdentifier"]; 
     _applicationId = ConfigurationManager.AppSettings["ApplicationId"]; 

     string encodedBody = string.Format("grant_type=password&username={0}&password={1}&scope={2} {3} {4} {0}" 
              , _userName, _password, _clientIdentifier, _userGuid, _applicationId); 
     request.AddParameter("application/x-www-form-urlencoded", encodedBody, ParameterType.RequestBody); 


     // execute the request 
     IRestResponse response = _client.Execute(request); 

     // Make sure everything is working as promised. 
     Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); 
     Assert.IsTrue(response.ContentLength > 0); 

     _token = new JavaScriptSerializer().Deserialize<Token>(response.Content).access_token; 

    } 

Далее идет следующий код, который вызывает метод Web.API, который проходит данный маркер по другому методу Web.API, где я выполняющий Добраться до извлеките некоторую информацию из моего сервиса.

 [TestMethod] 
    public void GetUserProfileTest() 
    { 

     // Arrange 
     var request = new RestRequest(string.Format("{0}{1}", _serviceRequestPrepender, "api/UserProfiles/UserProfiles/Get/{appId}/{userId}/{username}"), Method.GET); 

     // Add header stuff 
     request.AddParameter("Content-Type", "application/json", ParameterType.HttpHeader); 
     request.AddParameter("Accept", "/application/json", ParameterType.HttpHeader); 
     request.AddParameter("Authorization", string.Format("{0} {1}", "Bearer", _token)); 

     request.AddUrlSegment("appId", "1"); 
     request.AddUrlSegment("userId", _userGuid); 
     request.AddUrlSegment("username", _userName); 

     // execute the request 
     IRestResponse response = _client.Execute(request); 

     // Make sure everything is working as promised. 
     Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); 
     Assert.IsTrue(response.ContentLength > 0); // do more when working 

    } 

Далее вызывается служба, но я разработал метод Web.API с помощью специальной проверки безопасности доступа. Это ОЧЕНЬ простая проверка безопасности, так как она проверяет, действительно ли токен действителен и не истек. Вот метод IsAuthorized этого атрибута:

 protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     // Custom Code here 
     return ValidityChecker.IsTokenValid(actionContext); 
    } 

ValidityChecker простой класс, который только проверяет, является ли маркер действителен:

public class TokenValidityChecker 
{ 
    public ClaimsPrincipal PrincipalWithClaims { get; private set; } 

    /// <summary> 
    /// Extracts out the ability to perform token checking since all Token checking attributes will need t his. 
    /// </summary> 
    /// <param name="actionContext"></param> 
    /// <returns></returns> 
    public bool IsTokenValid(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     bool result = false; 

     var principal = actionContext.RequestContext.Principal; 
     if (principal.GetType() == typeof(ClaimsPrincipal)) 
     { 
      PrincipalWithClaims = (ClaimsPrincipal)principal; 
      result = PrincipalWithClaims.Identity.IsAuthenticated; 
     } 

     // Custom Code here 
     return result; 
    } 
} 

Так, с фоном на месте - здесь вопрос. Как вы можете видеть, обычно, когда услуга называется, ValidityChecker получит HttpActionContext. Наряду с этим, RequestContext.Principal этого HttpActionContext обычно имеет тип ClaimsPrincipal.

Однако при работе с модульным тестом и использовании RestSharp это, конечно же, WindowsPrincipal.

Есть ли способ использовать RestSharp, чтобы сделать это ClaimsPrincipal? Я попытался обеспечить, чтобы токен был включен в заголовок с использованием параметра авторизации, но не имел никакой удачи.

ответ

1

Хорошо. Если бы я просто прочитал детали моего собственного кода, я мог бы закончить это давно.

Ответ был ОЧЕНЬ прост. Код в вопросе добавляет токен к параметрам, но не аннотирует его как HttpHeader. Я забыл поместить это в вызов метода. Вот строка, которая фиксируется его:

  request.AddParameter("Authorization", string.Format("{0} {1}", "Bearer", _token), ParameterType.HttpHeader); 

«ParameterType.HttpHeader» в вызове метода сделал трюк.