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

本文关键字:重定向 服务 WCF 表单 身份验证 调用 | 更新日期: 2023-09-27 18:24:10

我试图通过调用一些方法来对我的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.

内部异常是找不到具有与登录重定向url对应的ResponseUri404。如果我禁用表单身份验证,则调用将正确通过。

我的问题是:

  1. 如何验证我的cookie是否正确接收
  2. 我如何检查它被拒绝的原因以及我被重定向到登录页面
  3. 我还有其他线索可以用来解决这个问题吗

编辑:最奇怪的原因是,如果我在对web服务进行两次调用之前在IIS中回收我的应用程序池,它们将正确通过而不会被重定向。

第2版:由于会话id cookie尚未创建,因此在回收应用程序池后,它似乎可以工作。在响应中,它出现在我的身份验证cookie之后。在随后的任何呼叫中,会话id cookie都会先出现,而我的第二个web服务似乎不喜欢看到会话id cookie先出现。。。?

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

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

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

安全web服务在响应标头中返回两个cookie。一个是会话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();
}

这非常有效。