Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify outgoing request headers (cookie) from async client (.NET Standard 2.0 vs .NET 4.7.2) #3511

Closed
eveneveneven opened this issue Mar 29, 2019 · 4 comments
Assignees

Comments

@eveneveneven
Copy link

Greetings!

Consider this scenario:

I've created a .NET Standard 2.0 library with WCF clients (async) generated by svcutil 2.0.0.
The external service requires some custom http header (cookie) for authentication.
In the library I've used an IClientMessageInspector to handle this. I've also tried creating an OperationContextScope and modifying the headers inside.

Both approaches work fine when using the library from a netcoreapp applicaton.
However using it from .NET 4.7.2 doesn't seem to respect my changes to the header.

I've wrestled with the OperationContext, and OperationContextScope as well trying to figure out the issue, but with no success.

I'm not sure if this is the right place for this issue, but surely someone will have some insight in the matter and can point me in the right direction?

Thanks for your time!

@Zek99
Copy link

Zek99 commented Apr 1, 2019

Have a look at #3442 and #3472 for additional inspiration. Unsure if it will work within .NET 4.7.2

@eveneveneven
Copy link
Author

Have a look at #3442 and #3472 for additional inspiration. Unsure if it will work within .NET 4.7.2

Thank you. Although I didn't find a solution yet, the issues you linked inspired me to try further.
Just to clarify, calling from netcoreapp is all good.
When using the library from .NET 4.7.x turns out I can actually add headers to the request.
However if the header is called "Cookie" it just seems do disappear (checking with Telerik Fiddler).

Example code:

public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            var token = aspNetToken;

            if (!string.IsNullOrWhiteSpace(token?.Value))
            {
                var property = new HttpRequestMessageProperty();
                property.Headers[HttpRequestHeader.Cookie] = new Cookie(token.Name, token.Value).ToString();
                request.Properties.Add(HttpRequestMessageProperty.Name, property);
            }

            return null;
        }

@eveneveneven eveneveneven changed the title Modify outgoing request from async client (.NET Standard 2.0 vs .NET 4.7.2) Modify outgoing request headers (cookie) from async client (.NET Standard 2.0 vs .NET 4.7.2) Apr 3, 2019
@Lxiamail Lxiamail added this to the Future milestone Apr 3, 2019
@mconnew
Copy link
Member

mconnew commented Apr 10, 2019

You might be running into a difference in cookie format support between .NET Framework and .NET Core. There were some gaps in support for the latest RFC's in .NET Framework which have been addressed in .NET Core. You can verify if this is the case by doing something like this on both runtimes:

            var mycookie = new Cookie(token.Name, token.Value).ToString();
            var uri = new Uri("http://example.com");
            CookieContainer container = new CookieContainer();
            container.SetCookies(uri, mycookie);

If there's a problem with the format of the cookie, it should throw CookieException. This exception gets silently swallowed when a Cookie is added via a header and not using a CookieContainer.

Btw, there's an easier way to manage cookies with WCF. You can write code similar to this:

    var factory = new ChannelFactory<IFoo>(new BasicHttpBinding() { AllowCookies = true },
                                           new EndpointAddress("https://example.org"));
    IFoo serviceProxy = factory.CreateChannel();
    IHttpCookieContainerManager cookieManager = ((IChannel)serviceProxy).GetProperty<IHttpCookieContainerManager>();
    cookieManager.CookieContainer.Add(new Uri("https://example.org"), new System.Net.Cookie(cookieName, cookieValue));

The issue where these changes are/were tracked is dotnet/corefx#29651. If the first code snippet doesn't throw an exception on .NET Framework, can you provide an example output from Cookie.ToString() for the token.

@eveneveneven
Copy link
Author

I read this as you were expecting this to throw an exception but I have to disappoint you there.
I added the container as you proposed and everything is working fine with both runtimes.

Cookie.ToString() is simply "token.name=token.value", might just be that I needed to use a CookieContainer.
I added the container like this in BeforeSendRequest as it works best with my current pattern:

var cookieManager = channel.GetProperty<IHttpCookieContainerManager>();
cookieManager.CookieContainer = container;

Both your suggestions were very helpful so thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants