dotnet / wcf

This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services.
MIT License
1.71k stars 558 forks source link

Missing ProtectionLevel property on ServiceContractAttribute #3386

Open menaheme opened 5 years ago

menaheme commented 5 years ago

I have installed the Nuget package System.ServiceModel.NetTcp , trying to invoke an existing WCF operation from a .Net Core 2.1 project.

The service's contract (that i do not cotrol) specifies ProtectionLevel.EncryptAndSign at the contract level. I can see the ProtectionLevel property in the source code of ServiceContractAttribute in this repo, and also in the decomplied assembly on my hard drive, but the compiler reports the classic

"The Type or namespace 'ProtectionLevel' could not be found"

The Enum ProtectionLevel itself is known to the compiler.

Using VS 2017 (15.9).

Lxiamail commented 5 years ago

@menaheme Looks like ProtectionLevel is not exposed in .Net standard contract. Does your scenario use MessageSecurity later? I'm wondering if this issue is the only issue blocking your app run on .NET Core.

mattilindroth commented 5 years ago

Hello, I also have this problem. I would need to set ProtectionLevel.Sign to ServiceContractAttribute, but alas I cannot. This is the only reason I cannot develop my software in dotnet core. Hope you'd push the priority of this up ;)

Lxiamail commented 5 years ago

@mattilindroth Does your scenario use MessageSecurity later?

phrohdoh commented 5 years ago

I am also running into this (ProtectionLevel not being in the .NET Standard I am targeting: 2.0).

I don't see MessageSecurity anywhere in my codebase (nor has it been explained how that is relevant, if we knew that we may be able to provide more information).

Is the 3.0 milestone this is assigned to .NET Core 3.0, .NET Standard 3.0, or 3.0 of a WCF lib?

mconnew commented 5 years ago

The ProtectionLevel property on ServiceContract is used to specify how MessageSecurity is applied to the soap message. With MessageSecurity, it's not required that everything in a soap message is part of the signature and not everything is encrypted. For example, if you set ProtectionLevel to Sign, then the soap message body will be included as part of the WS-Security message signature but the body will be sent unencrypted. Sometimes you don't care that anyone can see the request, but you do care to make sure nobody has modified it since the originator created it. If you set ProtectionLevel to EncryptAndSign, then the message body will be encrypted too. There's different granularity that you can set this on. ServiceContractAttribute is used to apply a single setting across all operations. You can override this per operation by setting ProtectionLevel on OperationContractAttribute. There are ways to override it on a per parameter basis too. The contract properties are only used when using MessageSecurity. If you aren't using MessageSecurity, then this property does nothing. If you want to modify the ProtectionLevel when using TransportSecurity, then you modify a ProtectionLevel property on the transport binding element.
As we don't support MessageSecurity on .NET Core, this property has no effect and no purpose. If the property were added to our api, modifying it shouldn't have any effect.

mconnew commented 5 years ago

To answer what I think your last question is, we will have a new release at the same time as .NET Core 3.0, but we are not moving forward our dependency to require .NET Core 3.0/.NET Standard 3.0 and currently have no plans to. The only thing which would make us do so is if there are new api's that there's a very compelling reason to use which would require it. We're staying at 2.0 so that you can still create a single library targeting netstandard2.0 which will work on .NET Core and .NET Framework.

makacenko commented 3 years ago

Hello, I have the same problem. I need to migrate a SOAP client of 3rd party service from .NET Framework to .NET Core.

Setting which successfully work on .NET Framework 4.7.2:

service.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;

where service is a contract/reference generated from wsdl by dotnet-svcutil targeting .net standard 2.1.

But on .NET Core 3.1, I cannot find how to set ProtectionLevel to value System.Net.Security.ProtectionLevel.Sign. This is necessary to make success call to the remote service - they support only this specific format of the SOAP message.

How can I achieve the same behavior on .NET Core?

hanogin commented 2 years ago

any new about this? @makacenko How did you solve this issue?

makacenko commented 2 years ago

@makacenko How did you solve this issue?

Microservices architecture. One (communication) microservice will be written in .NET Framework 4.8 :-(

mconnew commented 2 years ago

What's the binding you are using? Setting ProtectionLevel.Sign requires Message security. I want to make sure there isn't a scenario I've missed where this is useful without full Message security.

hanogin commented 2 years ago

@makacenko How did you solve this issue?

Microservices architecture. One (communication) microservice will be written in .NET Framework 4.8 :-(

Thanx, that's what i did as well.

hanogin commented 2 years ago

@mconnew I used it with consuming a wcf service with 509 certificate that install on the local machin, If i didn't add the line client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign; I wasn't able to make the call

mconnew commented 2 years ago

@tim6400, I don't suppose you know the binding that was used? I've tried to find where this might be getting used and could only find scenarios which use full Message security. The code in this area is really difficult to grok so it sounds like I missed something. Knowing the specific scenario would help make sure that scenario is supported.

SoporteExides commented 2 years ago

Same problem in NET 6 WPF application. I need to set up

_client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.None

Since I cannot do it in Net 6 application, every method in web service return "Invalid Security Header". It is critical for us to solve it. Any idea?

PabloSalinas27 commented 1 year ago

What's the binding you are using? Setting ProtectionLevel.Sign requires Message security. I want to make sure there isn't a scenario I've missed where this is useful without full Message security.

@mconnew Im using the WSHttpBinding since i need to consume SOAP through a third party provided WSDL and I need the same client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;. Is there a way to set the ProtectionLevel of the WSHttpBinding? Looking at System.ServiceModel.WSHttpSecurity I see public SecurityMode Mode { get; set; }... Which is not the same enum as ProtectionLevel. Are equivalent in some way? If so, could you point me towards an example? (or provide one please :) ) Thanks.

mconnew commented 1 year ago

Are you using the default constructor for WSHttpBinding? If so, that's using SecurityMode.Message (an optional constructor parameter) by default and that's not supported. If not, what does your instantiating WSHttpBinding look like?

mconnew commented 1 year ago

@SoporteExides, can you provide your binding? As I mentioned earlier, I couldn't find a way for that to be used other than in unsupported scenarios. I basically need enough info that I can replicate the security configuration that you are using on .NET Framework in a sample app then look at the request/reply messages to see what it's affecting. By the way, on .NET Framework you can set the ProtectionLevel on the ServiceContractAttribute on your contract interface and it gets copied to ContractDescription.ProtectionLevel.
Part of the problem is I need to write a test to validate the API is working as expected and without a known scenario to test, it could result in adding the API to the package contract and it still not working as there might be other code missing which uses it.

PabloSalinas27 commented 1 year ago

@mconnew I was trying to port some 4.8 client code that communicated with a service using WS-Security 1.0. with X509 Token Profile 1.0. On that code there is a CustomBinding, which is using some element bindings (like AsymmetricSecurityBindingElement and TextMessageEncodingBindingElement), on top of an "raw" HttpsTransportBindingElement. As AsymmetricSecurityBindingElement isn't in .Net6, I tried to use the WSHttpBinding hoping it would take care of placing the signature in the SOAP header after setting the certificates right, but without an option to set the ProtectionLevel to Sign, i guess it won't work so we will make a proxy on FW 4.8 to take care of it and call it from our .Net 6 server.

mconnew commented 1 year ago

AsymmetricSecurityBindingElement is full Message security and isn't supported yet.

PabloSalinas27 commented 1 year ago

@mconnew So I suppose that currently there is no way of consuming a service using WS-Security 1.0. with X509 Token Profile 1.0? We will use a proxy then, thanks for your time!

penev92 commented 1 year ago

@mconnew Are there plans to support AsymmetricSecurityBindingElement? I need to update some .NET Framework 4.8 code to .NET6+, which:

I gather that currently this is not possible? So I'd like to know if there's something that could be done. Thanks!

kierondye commented 5 months ago

I’m having the same problem with ContractDescription but I’m confused because the source code appears to show ProtectionLevel exists - https://github.com/dotnet/wcf/blob/5bae95f33dc19a8e62c26ab619f5106caa83aa56/src/System.ServiceModel.Primitives/src/System/ServiceModel/Description/ContractDescription.cs#L88

What am I missing?

delixfe commented 1 week ago

Add to: Support for Message Security #5641