使用表单身份验证调用WCF服务时避免重定向

时间:2014-09-24 15:27:22

标签: c# wcf

我试图通过调用一些方法对我的Web服务进行单元测试,但是我一直在点击登录页面重定向而不是获得实际结果。

我首先调用我的安全服务,它返回一个cookie,然后我可以重用该cookie来调用我的其他Web服务。我认为这是避免重定向的方法。

string sharedCookie;

var securityWebService = new SecurityWebServiceClient(CreateCustomBinding(), new EndpointAddress("http://localhost/SecurityWebService.svc"));
using (new OperationContextScope(securityWebService.InnerChannel))
{
    securityWebService.Login("UserName", "Password");

    var response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name];
    sharedCookie = response.Headers["Set-Cookie"];
}

var webService = new WebServiceClient(CreateCustomBinding(), new EndpointAddress("http://localhost/WebServiceWithFormsAuthentication.svc"));

using (new OperationContextScope(webService.InnerChannel))
{
    var request = new HttpRequestMessageProperty();
    request.Headers["Cookie"] = sharedCookie;
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = request;

    var data = webService.GetSomething();
}

错误如下:

There was no endpoint listening at http://localhost/WebServiceWithFormsAuthentication.svc that could accept the message.

内部异常是找不到404ResponseUri对应于登录重定向网址。如果我禁用表单身份验证,则正确地进行呼叫。

我的问题是:

  1. 如何验证我的Cookie是否已正确接收?
  2. 如何检查被拒绝的原因以及我是否被重定向到登录页面?
  3. 我可以遵循哪些其他线索来解决这个问题吗?
  4. 编辑:出于最奇怪的原因,如果我在调用Web服务之前在IIS中回收我的应用程序池,它们就会正确地通过而不会被重定向。

    编辑2 :由于尚未创建会话ID Cookie,因此在我回收应用池后,它似乎有效。在响应中,它出现在我的身份验证cookie之后。在任何后续调用中,会话ID cookie首先出现,看起来我的第二个Web服务看起来不像首先出现会话ID cookie ...?

    编辑3:我的身份验证服务启用了会话,而我的普通网络服务并没有。当会话cookie首先出现在标题中时,似乎第二个人不喜欢它。也许它不期望首先看到另一个cookie?

1 个答案:

答案 0 :(得分:1)

这就是我做的工作。我必须做到这一点似乎很奇怪,所以如果有人有更好的解决方案,我想听听。

安全Web服务在响应头中返回两个cookie。一个是会话cookie,另一个是身份验证cookie。我所做的是在一个cookie容器中解析标题,只提取身份验证cookie,只发送一个到另一个Web服务。

string sharedCookie;

var securityWebService = new SecurityWebServiceClient(CreateCustomBinding(), new EndpointAddress("http://localhost/SecurityWebService.svc"));
using (new OperationContextScope(securityWebService.InnerChannel))
{
    securityWebService.Login("UserName", "Password");

    var response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name];
    var cookieHeader = response.Headers["Set-Cookie"];
    var container = new CookieContainer();
    container.SetCookies(new Uri("http://localhost"), cookiesString);
    var cookies = container.GetCookies(new Uri("http://localhost"));

    var authCookie = cookies["nameOfAuthCookie"];
    if (authCookie != null)
         sharedCookie = authCookie.ToString();
}

这很有效。