我在使用RestSharp测试我的Web.API方法的特定实现方面遇到了一些麻烦。我在开放(非安全)方法中执行POSTS和GETS非常成功。但是,当我必须发送令牌以确定访问权限时,我会遇到问题。
以下是实施:
我正在为我的Web.API使用OWIN中间件。客户端必须发送到令牌服务才能获得包含其声明的给定令牌。所有这一切都运作良好。
在我的测试中,我的初始化程序具有以下代码,该代码发布到令牌服务并获取令牌。这非常有效 - 按照宣传的那样返回令牌:
[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参数确保令牌包含在标头中,但没有任何运气。
答案 0 :(得分:1)
好吧 - 如果我只是阅读我自己的代码的细节,我很久以前就可以完成这个。
答案非常简单。问题中的代码将令牌添加到参数中,但不会将其注释为HttpHeader。我忘了把它放到方法调用中。以下是修复它的行:
request.AddParameter("Authorization", string.Format("{0} {1}", "Bearer", _token), ParameterType.HttpHeader);
&#34; ParameterType.HttpHeader&#34;在方法调用中做了伎俩。