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

EnableUnsecuredResponse flag not supported #3653

Closed
MaxiPigna opened this issue May 27, 2019 · 14 comments
Closed

EnableUnsecuredResponse flag not supported #3653

MaxiPigna opened this issue May 27, 2019 · 14 comments
Labels
Backlog Legitimate tasks of lower priority not in current dev schedule. bug This is a product bug.

Comments

@MaxiPigna
Copy link

Hello, I am migrating an application which contains some WCF services calls from .NET Full to .Net Core. Unfortunately, one of these services could not be implemented because it requires a Custom Binding with the following security element:

securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
securityElement.IncludeTimestamp = true;
securityElement.LocalClientSettings.DetectReplays = false;
securityElement.LocalServiceSettings.DetectReplays = false;
securityElement.EnableUnsecuredResponse = true;

EnableUnsecuredResponse flag is not available in .Net Core and without setting that flag I get a well known exception TransportSecurityBindingElement.BuildChannelFactoryCore is not supported.
I didn't find any valid workaround for that. It would be great to have this feature supported in the next release.

@StephenBonikowsky
Copy link
Member

Adding @mconnew
@MaxiPigna if you are able to provide a simple client and server for this scenario it would assist with adding support for the flag.

@StephenBonikowsky StephenBonikowsky added feature request Adding new functionality requiring adding an API to the public contract. needs more info Need more info in order to reproduce the issue. labels May 29, 2019
@StephenBonikowsky
Copy link
Member

From @mconnew

I just had a quick search for anything about that property and I believe the issue is down to the security header being written on the wire like:

    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"></wsse:Security>

vs

  <wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>

The first one has a security header with content which is zero length, the second one has no content. It’s semantically the different between having a list of child nodes which is empty vs the list itself being null. Apparently WCF trips up if it gets something it’s not expecting.

We are doing some additional investigating and gathering of info to make sure we have correctly identified the issue. That being the case a possible workaround would be to create a custom message encoder that would either modify the security header or remove it altogether.

A code fix is probably the right way to go but it may not make it into the 3.0 release time frame.

@StephenBonikowsky
Copy link
Member

After some additional investigation it looks like the issue is the difference between having no security header at all versus having a security header with no content.

From @mconnew the short-term workaround is to

create a modified message encoder and add that header in with no contents.

We will consider what the correct long-term fix is for a future release.
Let us know if there is anything else we can do.

@StephenBonikowsky
Copy link
Member

Moving to future work.

@StephenBonikowsky StephenBonikowsky added Backlog Legitimate tasks of lower priority not in current dev schedule. bug This is a product bug. and removed needs more info Need more info in order to reproduce the issue. feature request Adding new functionality requiring adding an API to the public contract. labels Jun 11, 2019
@StephenBonikowsky StephenBonikowsky added this to the Future milestone Jun 11, 2019
@maheshnlrb
Copy link
Contributor

I see that TransportSecurityBindingElement have the EnableUnsecuredResponse flag, but it;s not being propagated by 'TransportSecurityBindingElement.Clone' method. (Because it calls 'new TransportSecurityBindingElement(this)' . This constructor does not initialize the EnableUnsecuredResponse property.

@mconnew
Copy link
Member

mconnew commented Jun 18, 2019

@maheshnlrb, I was just going to suggest you submit a pull request, then saw you already have!

@MaxiPigna
Copy link
Author

Hello, finally I solved by following @mconnew's suggestion. This is a sample code provided by
@mconnew to implement a Custom Message Encoder by wrapping an existing Message Encoder. It has been very helpful! 😊

@StephenBonikowsky
Copy link
Member

@MaxiPigna glad @mconnew was able to help. Let us know if there is anything else we can do.

@echavez087
Copy link

echavez087 commented Aug 8, 2019

Custom Message Encoder

@MaxiPigna Can you provide an specific example of how you ended up implement the missing property please?

@MaxiPigna
Copy link
Author

@MaxiPigna Can you provide an specific example of how you ended up implement the missing property please?

@echavez087 my previous message contains the link with the example. For semplicity, here it is:
https://github.com/dotnet/wcf/files/3307783/CustomMessageEncoder.zip

@echavez087
Copy link

echavez087 commented Aug 9, 2019

@MaxiPigna Can you provide an specific example of how you ended up implement the missing property please?

@echavez087 my previous message contains the link with the example. For semplicity, here it is:
https://github.com/dotnet/wcf/files/3307783/CustomMessageEncoder.zip

Thanks for your reply @MaxiPigna I did take a look at the sample, I just was't able to figure out how to add the missing property using that sample. I would really appreciate if you could help me figure it out. Sorry I don't have much experience with WCF. Thanks.

@MaxiPigna
Copy link
Author

Basically the problem was that the response message didn't contain a security header.

From @mconnew

I just had a quick search for anything about that property and I believe the issue is down to the security header being written on the wire like:

    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"></wsse:Security>

vs

  <wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>

The first one has a security header with content which is zero length, the second one has no content. It’s semantically the different between having a list of child nodes which is empty vs the list itself being null. Apparently WCF trips up if it gets something it’s not expecting.

We are doing some additional investigating and gathering of info to make sure we have correctly identified the issue. That being the case a possible workaround would be to create a custom message encoder that would either modify the security header or remove it altogether.

A code fix is probably the right way to go but it may not make it into the 3.0 release time frame.

The workaround proposed was to manually add that header (an empty value is enough) to the response when reading the message. So, if you look at the CustomMessageEncoderFactory you see that the two ReadMessage methods before returning the message, they add an empty security header.

private Message AddSecurityHeader(Message message)
{
        var header = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "", true);
        message.Headers.Add(header);
        return message;
}

@echavez087
Copy link

AddSecurityHeader

@MaxiPigna thank you very much for the detailed explanation it helped me to understand much better. :)

@chriszumberge
Copy link

@MaxiPigna I tried your suggestion but got the error,

"The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding. "

If I use any other security mode the server tells me I have an invalid username and password.

// https://github.com/dotnet/wcf/issues/2219
MethodInfo method = typeof(XmlSerializer).GetMethod("set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
method.Invoke(null, new object[] { 1 });

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
SubmitCustomerData submitCustomerData = JsonConvert.DeserializeObject<SubmitCustomerData>(requestBody);

var binding = new System.ServiceModel.BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;

var customBinding = new CustomBinding(binding);
var elements = customBinding.Elements;
var i = -1;
for (i = 0; i < elements.Count; i++)
{
    if (typeof(MessageEncodingBindingElement).IsAssignableFrom(elements[i].GetType()))
        break;
}
var mebe = (MessageEncodingBindingElement)elements[i];
elements[i] = new CustomMessageEncodingBindingElement(mebe);

// https://community.workday.com/sites/default/files/file-hosting/productionapi/Revenue_Management/v35.0/Revenue_Management.wsdl
EndpointAddress address = new EndpointAddress("https://our_own_implementation_address/Revenue_Management/v35.0");

Revenue_ManagementPortClient rm = new Revenue_ManagementPortClient(customBinding, address);
rm.ClientCredentials.UserName.UserName = "username";
rm.ClientCredentials.UserName.Password = "password";

where

public partial class Revenue_ManagementPortClient : System.ServiceModel.ClientBase<Revenue_ManagementPort>

If I set a breakpoint at return message; in your CustomMessageEncoderFactory.AddSecurityHeader(Message message) method, the message at that point is the correct response from the server.. it's like the client sees the added Security header and rejects the whole thing.
If I don't add the Security header via your encoder, then I get the error that started this whole issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backlog Legitimate tasks of lower priority not in current dev schedule. bug This is a product bug.
Projects
None yet
Development

No branches or pull requests

6 participants