How do i send a cookie from web app to wcf service?

285 views Asked by At

I'm sure this is not a new question but the truth is that I've not been able to make it work. I have a C# web forms app that authenticates the user and after validating it creates a cookie and calls a WCF service.

I'm fairly new to WCF so any help will be much appreciated.

Thank you.

Web forms app:

if (validUser)
{
        FormsAuthenticationTicket tkt;
        string cookiestr;
        HttpCookie ck;
        tkt = new FormsAuthenticationTicket(1, TextBox1.Text, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie, "sample data");
        cookiestr = FormsAuthentication.Encrypt(tkt);
        ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
        if (chkPersistCookie)
            ck.Expires = tkt.Expiration;
        ck.Path = FormsAuthentication.FormsCookiePath;
        Response.Cookies.Add(ck);

        string strRedirect;
        strRedirect = Request["ReturnUrl"];
        if (strRedirect == null)
            strRedirect = "default.aspx";

        //Calling wcf service
        ServiceReference1.Service1Client ServCli1 = new ServiceReference1.Service1Client();
        ServCli1.GetData(12);
}

wcf service:

 public string GetData(int value)
    {
        string xpto = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];
        var xpto1 = HttpContext.Current.Request;
        return string.Format("You entered: {0}", value);
    }

The problem is that the wcf service never receives the cookie and i need it so that i can validate the user inside the wcf service.

web client web.config:

<system.web>
    <compilation debug="true" targetFramework="4.6.1"/>
    <httpRuntime targetFramework="4.6.1"/>
    <pages>
      <namespaces>
        <add namespace="System.Web.Optimization"/>
      </namespaces>
      <controls>
        <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt"/>
      </controls>
    </pages>
    <authentication mode="Forms">
    </authentication>
    <authorization>
      <deny users="?"  />
      <allow users="*"   />
    </authorization>
  </system.web>

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService1" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:58515/Service1.svc" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
        name="BasicHttpBinding_IService1" />
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

wcf web.config:

 <system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1"/>
    <authentication mode="Forms">
    </authentication>
    </system.web>
  <system.serviceModel>

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
1

There are 1 answers

0
Ding Peng On

You can use OperationContextScope to create a new context in the client-side application to add custom headers to outgoing messages. You can use this method to pass cookies to the server-side.Here is my demo:

     HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
        httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, "<Test Cookie>");

        using (OperationContextScope scope = new OperationContextScope(service1Client.InnerChannel))
        {
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
            service1Client.YZ();
        }

This is the client-side code. Use OperationContextScope to pass cookies to the server-side.

        public void YZ()
    {
        string xpto = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];
        Console.WriteLine(xpto);
    }

This is the server-side code. After successful execution, the cookie will be output.

For more information about OperationContextScope,Please refer to the following link:

https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.operationcontextscope?view=dotnet-plat-ext-3.1