Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与[授权]集成测试Web Api_C#_Asp.net Web Api_Web Config_Integration Testing_Authorize Attribute - Fatal编程技术网

C# 与[授权]集成测试Web Api

C# 与[授权]集成测试Web Api,c#,asp.net-web-api,web-config,integration-testing,authorize-attribute,C#,Asp.net Web Api,Web Config,Integration Testing,Authorize Attribute,所以我在[Authorize]标签上找到了一些启发我的东西,但没有任何东西能解决我的问题 我的场景是,我有一些Web Api方法,我希望使用RestSharp进行集成测试。然而,RestSharp得到的是我的登录页面,而不是通话结果 [Authorize] public Item GetItem([FromBody] int id) { return service.GetItem(id); } 该产品使用自定义登录系统,我真正想要的是一种仅在集成测试中禁用[Authorize]徽章的

所以我在[Authorize]标签上找到了一些启发我的东西,但没有任何东西能解决我的问题

我的场景是,我有一些Web Api方法,我希望使用RestSharp进行集成测试。然而,RestSharp得到的是我的登录页面,而不是通话结果

[Authorize]
public Item GetItem([FromBody] int id) 
{
   return service.GetItem(id);
}
该产品使用自定义登录系统,我真正想要的是一种仅在集成测试中禁用[Authorize]徽章的方法。但是我听说你可以允许匿名用户,这会“禁用”徽章,所以在解决方案中,我有一个集成测试项目,在该项目中我有一个App.config文件。在该文件中,我提出:

 <location>
  <system.web>
   <authorization>
     <allow users="?"/>
    </authorization>
  </system.web>
 </location>

但这似乎也不起作用。任何关于发生了什么,为什么它不起作用,以及可以做些什么使它起作用的解释都将不胜感激


我试图设置Thread.CurrentPrincipal,但没有成功(可能是我做错了-你能在代码中设置“任何”被授权吗?)。如果有任何帮助,则在httpmodule中处理身份验证。

为您的
RestClient
设置身份验证程序:

RestClient.Authenticator = new HttpBasicAuthenticator(username, password);
使用自定义登录系统实际接受的身份验证程序。。。基本,NTLM,OAuth,简单


在示例的第二行中有一些文档记录在这里是如何设置
线程.CurrentPrincipal
。将这样的消息处理程序添加到Web API项目中,并在
WebApiConfig.cs
Register
方法中添加该处理程序,如下所示:
config.MessageHandlers.Add(new MyTestHandler())


顺便说一句,对于集成测试,我更愿意使用内存托管,而不是web托管。这样,WebAPI在同一个测试项目中运行,您可以用它做任何您想做的事情,而不用担心在生产中破坏某些东西。有关内存托管的更多信息,请参阅和。

我意识到这个问题是关于在webapi端点从RestSharp触发“真实”请求的,因此此建议不立即适用于OPs场景。。但是:

我正在使用内存中的Web Api测试,使用的是
HttpConfiguration
HttpServer
HttpMessageInvoker
(很像我相信的那样)。通过这种方式,我不需要打开侦听器或端口,因为我可以在内存中测试完整的堆栈(端到端测试)——在构建服务器、Heroku实例等上非常方便

使用内存测试,下面是如何设置
线程.CurrentPrincipal
。。我的测试基类上有一个助手,如下所示:

protected void AuthentateRequest()
{
    Thread.CurrentPrincipal = new AuthenticatedPrincipal(Thread.CurrentPrincipal);
}
它使用这个:

public class AuthenticatedPrincipal : IPrincipal
{
    private readonly IPrincipal _principalToWrap;
    private readonly IIdentity _identityToWrap;

    public AuthenticatedPrincipal(IPrincipal principalToWrap)
    {
        _principalToWrap = principalToWrap;
        _identityToWrap = new AuthenticatedIdentity(principalToWrap.Identity);
    }

    public bool IsInRole(string role)
    { return _principalToWrap.IsInRole(role); }

    public IIdentity Identity
    {
        get { return _identityToWrap; }
        private set { throw new NotSupportedException(); }
    }
}

public class AuthenticatedIdentity : IIdentity
{
    private readonly IIdentity _identityToWrap;

    public AuthenticatedIdentity(IIdentity identityToWrap)
    {
        _identityToWrap = identityToWrap;
    }

    public string Name
    {
        get { return _identityToWrap.Name; }
        private set { throw new NotSupportedException(); }
    }
    public string AuthenticationType
    {
        get { return _identityToWrap.AuthenticationType; }
        private set { throw new NotSupportedException(); }
    }
    public bool IsAuthenticated
    {
        get { return true; }
        private set { throw new NotSupportedException(); }
    }
}
手动存根
IPrincipal
似乎有些过分,但我尝试了使用my,但在我的一些测试运行程序中失败了(Resharper和TeamCity,但不是NCrunch,我认为这是关于在应用程序域上序列化的事情)


这将在
ApiController
操作方法中设置
Thread.CurrentPrincipal
,从而愚弄
AuthorizeAttribute
使其相信您已通过身份验证。

这实际上与Web API中的常规登录系统一起工作,可能是您的自定义登录系统正在执行其他操作。。。您的登录系统是否接受基本身份验证?您是否尝试过在restsharp中使用不同的验证器?还有其他一些,如NTLM、Simple、OAuth……如果有帮助的话。。。我正在使用FedAuth登录。所以您有令牌供用户登录。。看看这篇文章,因为他们使用OAuth身份验证传递秘密和令牌,而这不是在内存中使用HttpServer时的答案。在测试WebAPI2操作时可以完美地工作。谢谢。更多关于这种测试方式的信息
protected void AuthentateRequest()
{
    Thread.CurrentPrincipal = new AuthenticatedPrincipal(Thread.CurrentPrincipal);
}
public class AuthenticatedPrincipal : IPrincipal
{
    private readonly IPrincipal _principalToWrap;
    private readonly IIdentity _identityToWrap;

    public AuthenticatedPrincipal(IPrincipal principalToWrap)
    {
        _principalToWrap = principalToWrap;
        _identityToWrap = new AuthenticatedIdentity(principalToWrap.Identity);
    }

    public bool IsInRole(string role)
    { return _principalToWrap.IsInRole(role); }

    public IIdentity Identity
    {
        get { return _identityToWrap; }
        private set { throw new NotSupportedException(); }
    }
}

public class AuthenticatedIdentity : IIdentity
{
    private readonly IIdentity _identityToWrap;

    public AuthenticatedIdentity(IIdentity identityToWrap)
    {
        _identityToWrap = identityToWrap;
    }

    public string Name
    {
        get { return _identityToWrap.Name; }
        private set { throw new NotSupportedException(); }
    }
    public string AuthenticationType
    {
        get { return _identityToWrap.AuthenticationType; }
        private set { throw new NotSupportedException(); }
    }
    public bool IsAuthenticated
    {
        get { return true; }
        private set { throw new NotSupportedException(); }
    }
}