在使用RestSharp测试我的Web.API方法的特定实现时,我遇到了一些问题。在我的open (非安全)方法中,我非常成功地执行了POSTS和GETS。但是,当我必须发送一个令牌来确定访问权限时,我就遇到了问题。
具体实现如下:
我在我的Web.API中使用了OWIN中间件,客户端必须发布到令牌服务,才能获得包含其声明的给定令牌。所有这些都运行得很好。
在我的测试中,我的Initializer有以下代码,它发送到令牌服务并取回令牌。这非常有效-返回广告中的令牌:
[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方法,我在该方法中执行GET以从我的服务中提取一些信息。
[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。除此之外,该HttpActionContext的RequestContext.Principal通常是ClaimsPrincipal类型。
但是,当从单元测试运行并使用RestSharp时,它当然是一个WindowsPrincipal。
有没有办法用RestSharp把它变成ClaimsPrincipal呢?我已经尝试使用Authorization参数确保令牌包含在头文件中,但没有任何成功。
发布于 2015-07-01 00:53:47
好吧-如果我只是简单地阅读我自己的代码的细节,我早就可以完成这项工作了。
答案很简单。问题中的代码将令牌添加到参数中,但没有将其注释为HttpHeader。我忘了把它放到方法调用中了。下面是修复它的代码行:
request.AddParameter("Authorization", string.Format("{0} {1}", "Bearer", _token), ParameterType.HttpHeader);方法调用中的"ParameterType.HttpHeader“做到了这一点。
https://stackoverflow.com/questions/31143439
复制相似问题