首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在ClaimsPrincipal中传递RestSharp来测试Web.API方法

如何在ClaimsPrincipal中传递RestSharp来测试Web.API方法
EN

Stack Overflow用户
提问于 2015-07-01 00:20:11
回答 1查看 2.4K关注 0票数 0

在使用RestSharp测试我的Web.API方法的特定实现时,我遇到了一些问题。在我的open (非安全)方法中,我非常成功地执行了POSTS和GETS。但是,当我必须发送一个令牌来确定访问权限时,我就遇到了问题。

具体实现如下:

我在我的Web.API中使用了OWIN中间件,客户端必须发布到令牌服务,才能获得包含其声明的给定令牌。所有这些都运行得很好。

在我的测试中,我的Initializer有以下代码,它发送到令牌服务并取回令牌。这非常有效-返回广告中的令牌:

代码语言:javascript
复制
 [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以从我的服务中提取一些信息。

代码语言:javascript
复制
        [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方法:

代码语言:javascript
复制
        protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        // Custom Code here
        return ValidityChecker.IsTokenValid(actionContext);
    }

ValidityChecker是一个简单的类,它只检查令牌是否有效:

代码语言:javascript
复制
    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参数确保令牌包含在头文件中,但没有任何成功。

EN

回答 1

Stack Overflow用户

发布于 2015-07-01 00:53:47

好吧-如果我只是简单地阅读我自己的代码的细节,我早就可以完成这项工作了。

答案很简单。问题中的代码将令牌添加到参数中,但没有将其注释为HttpHeader。我忘了把它放到方法调用中了。下面是修复它的代码行:

代码语言:javascript
复制
            request.AddParameter("Authorization", string.Format("{0} {1}", "Bearer", _token), ParameterType.HttpHeader);

方法调用中的"ParameterType.HttpHeader“做到了这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31143439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档