У меня возникли проблемы с конкретной реализацией тестирования методов 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? Я попытался обеспечить, чтобы токен был включен в заголовок с использованием параметра авторизации, но не имел никакой удачи.