Customer has a large deployment of WCF services that use _WsHttpBinding_ & _WsFederationHttpBinding_. They are currently developing.NET Core based front-end Web APIs (using ASP.NET 5) that would have to consume these services. Without support for these WS-* bindings, there is no way to call these services securely using federated security. Enabling WS-* on the WCF client would enable these interop scenarios for large enterprises.
Thanks for the suggestion @sujitdmello . Let's use this issue to discuss it and collect other input from the community. Inviting @iamjasonp and @mconnew for their thoughts.
My input:
WS-* is absolutely necessary for any SOAP based stack for interoperability with other WS technologies or in case of existence of an IdP (Identity Provider).
Almost any decent sized WCF based application will make use of WS-* (maybe WS-Trust being the most common). If Core WCF is reduced to a SOAP alternative to REST services with minor additions then there's no point in Core WCF at all. If Core WCF cannot be used interoperably with other WS-* stacks (IE: Full .Net WCF), then there's no point in it either.
From a security point of view Username, Certificate and Windows authentication is simply insufficient especially when considering cloud and hybrid platforms, WS-* extensions are needed for this scenario.
My 2c.
Good feedback, @popcatalin81 and @sujitdmello - thanks!
Our first cut of the APIs in the WCF client for .NET Core was based on what was available on the API surface for Windows Store 8 apps... (maybe this list will look familiar :smiley: WCF in Metro apps).
I'm of the opinion too that WS-* protocols present in WCF desktop should be supported.
WCF on the desktop supported these protocols... I've come up with a (likely incomplete) list of things that isn't supported yet in no particular order:
So... what protocols does the community think is important to have in WCF client?
WS-Federation and WS-Trust are extremely important, and I would love to see support for WS-Federation made available in coreclr by bringing in large parts of System.IdentityModel/Windows Identity Froundation (I assume this is a precursor to WCF supporting it).
We have a scenario where we would need WS-Federation and WS-Trust in a UWP context. Are there some plans to finally make this happen?
In the meantime, are there alternatives, e.g. libraries/packages that already implemented this that we could use?
Any updates on WS-* support? The information I've found is extremely sparse.
Apologies @CountZachula @dersteve and others on this thread -- there have been no updates on this while we've been heads down on the pending release. But we hear this request and are building out our plan for next features, so requests like yours are helping set the priorities. We're tracking them with this query.
If there are other mission critical features not yet available, please continue to open issues for them and double-check that we have triaged and understood them appropriately.
We will shortly publish an updated Supported Feature Matrix and hopefully a roadmap based on your requests.
So does that mean we can't use anything that would require a WsHttpBinding? I'm getting a content type text/xml charset=utf-8 was not supported by service which back in .NET you were using a basic binding when you should be using WS.
Same here @StrangeWill - need wsHttpBinding for a svc i'm trying to consume in a UWP....
@bc3tech Check out #1370, I'm consuming a service I'd need wsHttpBinding for using CustomBinding code from that issue, so far so good.
I need wsHttpBinding to work so I can hit a on-premise estore (http://www.nodus.com/documentation/eSSS_501_API_Developer_Guide.pdf). I tried using CustomBindings with http but it didn't work - it could be because I need provide Windows credentials.
@pholly Have you tried setting channelFactory.Credentials and httpBindingElement.AuthenticationScheme from the code sample in #1370?
@StrangeWill These are the errors I'm getting so now I'm not sure if it's even rejecting it because of credentials:
An unhandled exception occurred while processing the request.
WinHttpException: The operation timed out
ProcessGetResponseWebException
HttpRequestException: An error occurred while sending the request.
ProcessGetResponseWebException
CommunicationException: An error occurred while sending the request.
ProcessGetResponseWebException
I'm not using a ChannelFactory - I used svcutil.exe to generate the client. One of the client constructors takes a Binding and an EndpointAddress so I'm using that one. Should I try to not use the generated client and use a ChannelFactory? The generated client has a way to specify credentials with this line:
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(username, password);
If I don't use the client, what httpBindingElement.AuthenticationScheme should I use?
Really appreciate the help and if you want me to provide more info just let me know. I may be able to query this estore's database directly but if I could use the api that would be so much better.
@pholly Ah, nah you're on the right track -- timeout exception hints that you need to increase the send/receive timeout though.
Edit: Or you don't have network connectivity to their APIs.
If it was a WS* binding error you'd be getting something completely different.
@StrangeWill I switched the endpoint to a network ip instead of a hostname and this is the error I get:
FaultException: The message could not be processed.
This is most likely because the action 'http://tempuri.org/ICustomers/GetCustomerbyUsername' is
incorrect or because the message contains an invalid or expired security context token or because
there is a mismatch between bindings.
The security context token would be invalid if the service aborted the channel due to inactivity. To
prevent the service from aborting idle sessions prematurely increase the Receive timeout on the
service endpoint's binding.
So I probably should try creating the request without the generated client?
@pholly You should be able to take a binding that works in .NET and use a custom binding for .NET Core by using custom bindings for this purpose, there is a tool here that may put you on the right track for converting it: http://webservices20.cloudapp.net/ (it is a custom binding for .NET not .NET Core, but it helps you break down sort of how to configure a .NET Core custom binding).
Sadly I don't have a service at my disposal right now to test this against. It looks like you should be able to create a SecurityBindingElement and add it to your custom binding. Not sure why the tool isn't handling that for you though.
Something down the road of this?
var securityBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
binding.Elements.Add(securityBindingElement);
@StrangeWill Thanks for the suggestion. I tried using a ChannelFactory and setting the Credentials.Windows.ClientCredential on it but I got the same error so I'll try using that SecurityBindingElement.
I get this error when using SecurityBindingElement:
PlatformNotSupportedException: TransportSecurityBindingElement.BuildChannelFactoryCore
is not supported.
As a workaround I am going to create an asp.net 4 api that interfaces with our estore and hit that from our asp.net core api.
@pholly Shoot, #1257, looks like it needs to be implemented before it's supported in .NET Core, unless one of the .NET Core WCF team members want to chime in with something I'm missing to get around this. :(
You're not missing anything - we'll get on it (#1257) shortly :)
I will use this issue as the main tracking issue for bringing WS* online. First step is #1257 which enables many of the core product pieces necessary for the rest. Transport level security with WS* is the first goal using a CustomBinding, with additional API's to follow.
This needs message protection from message security feature, which is unavailable currently.
Any updates as to when this may be available or if there are any reasonable work arounds?
Need an update on this, we are considering using .net core for a project but we are currently blocked by this.
@coreyakaplan @brizo001 sorry for late response. The work involved for this feature is non-trivial for WCF, aside from blocking issues/missing dependencies,. This is not on any of our short term plan. There are a lot of great feedback/discussions on this thread. Please also vote the issue - it will be easier to tell the number of requests in future planning.
Hello. I am working on HR software that integrates with E-Verify, a government WCF service to verify employment eligibility. We wanted to migrate a currently .NET 4.6 WepAPI service to .NET Core, however, found a limitation. I believe this particular API may warrant some consideration of implementing this binding.
The E-Verify web service requires using wsHttpBinding with TransportWithMessageCredential and SecurityType.None. This specific combination seems to be very proprietary of .NET WCF services. This tells me that _potentially all consumers_ of this government API may be forced to integrate either with .NET 4.6 or have a solution to doing this without using .NET. I am currently researching the E-Verify API for options on other ways to use this service but the default service reference added in .NET generates this particular binding for communication out of the box.
Many examples I found to implement this specific protocol in another language always end up using a WCF site as a proxy in between their NodeJS or Java client. If anyone has a solution that can be implemented without WCF please let me know.
It is very likely that either the Department of Homeland Security needs to make their API less proprietary to make integration from other languages easier (unlikely), or we should support this in .NET Core if any modern .NET applications are going to be built to integrate with it. Thanks for any help you can offer.
I've been thinking about this issue quite a bit lately and I really want to find a solution. Unfortunately our dependencies are absent for us to enable this in an identical way as exists on the full framework. So I have two questions.
For full transparency, I'm investigating the feasibility of supporting asp.net core style WS-Fed authentication which is done via HTTP headers and making that consumable on the server side via a behavior.
Thanks for the response. I was trying to be very explicit when mentioning the E-Verify DHS system. To answer your questions:
E-Verify just released an updated binding configuration for their latest setup. Previously it was:
<binding name="WSHttpBinding_IEmployerWebService">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
The latest is that they require establishSecurityContext=false as described here
<binding name="WSHttpBinding_IEmployerWebService">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
E-Verify also supports BasiHttpBinding but only with the security mode set to BasicHttpsSecurityMode.TransportWithMessageCredential, which is also not supported in the current implementation.
ExactTargets FuelSDK seems to require this. Unfortunately their rest api does not support all operations necessary for my use case so I am not able to use .net standard 2.0 for this project.
At he moment I am struggling to implement
Maybe the best way would be implementing a custom IClientMessageInspector?
Think this is blocking me from communicating to government web services communication as well. Tried using "Microsoft WCF Web Service Reference Provider" for Core, and it used a CustomBinding with the HttpsTransportBindingElement. Works for small payloads, but as soon as it gets above some size (~16k 2-byte chars) the request times out. Not sure if that means anything to anyone here. Unfamiliar with this architecture.
I have developed many WCF applications for my enterprise customers and all of them make use of WSTrust. Not having support for WSTrust is obviously the biggest road blocker from migrating to .Net core. Hope that this will be supported soon :smile:
Many of our Enterprise Apps rely on WSBinding and would like to +1 the request for this feature.
I'm having the same issue. Can't figure out a CustomBinding that works, either.
I was hoping to see this on the roadmap for 2.1 but no such luck...
Same issue here. Lack of WsBinding stops our project to be migratied to EF Core, which would be a nice thing to do. So I'll leave my +1 here as well.
I would classify the need for the various WS-* standards into two main camps:
Specific support for the standard required
This could be for example integrating with a third party web service such as the E-Verify government system that @gtaborga has stated is his requirement. Or it could be communicating with a Java SOAP service stack.
Authentication support from third party token providers required using WCF end to end
This would be token support such as OAuth. As you can't generally use arbitrary authentication tokens with transport security, you need to use message security for authentication.
I'd like to get an idea of how many people would be unblocked by providing a solution to the second category. The problem with have is we build our WS-* security standards support on top of System.IdentityModel and the team which owns this currently has no plans to port this code to .Net Core. If we could provide a way to use token authentication in a similar manner that asp.net core supports but without using the WS-* protocols and we provided the necessary binding elements to use with WCF on the full framework as well as .Net core, how many could and would use this as a solution? I understand there are some who can only use a full implementation of the WS-* protocols, unfortunately that's not possible right now so we're investigating options to solve at least some scenarios.
Thank you @mconnew for the update. I can understand the predicament with System.IdentityModel. This kind of information hopefully can be used to inform the team maintaining E-Verify that their solution needs updating in the long haul. I will follow up with our team and E-Verify to see what options are possible for them and us moving forward given this reality.
@mconnew thanks for the update, we wont be blocked by just having the 2 implemented. Do you have any timelines on when 1 will be implemented?
Any updates on this?
@roncain @iamjasonp @mconnew Any news on this?
Any updates on this?
It's on our schedule to work on a prototype, which could unblock #2. Will update this thread once we have more progress.
any updates?
@Lxiamail #2 is marked as Closed ... seems like if it's still on the table it shouldn't be Closed?
@bc3tech Sorry, I meant https://github.com/dotnet/wcf/issues/8 instead of https://github.com/dotnet/wcf/issues/2.
any updates?
@etosson Unfortunitely, due to other high priority work items, #2 is in prototype phase.
any updates?
@balduinoman no, we won't be able to make progress in near term.
any updates?
Just in case someone is also interested in using WSTrust and WCF: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/852
I had to do it on my own, here is the solution I developed, might work for some of you too.
https://stackoverflow.com/a/52696777/5077196
+1
@yahya99223 I ended up doing like you. However, processing the response is terrible if you receive an envelope that you are not expecting.
Hello there. Yahya, WS-Security 1.1 can be provided this way. Thank you for your suggestion. The service I want to connect to requires WS-Security 1.1, WS-Trust 1.3 and WS-SecurityPolicy 1.2 standards. I cannot provide the WS-trust standard with this method. I am writing a sample for the binding and enpoint configuration of an .net framework-enhanced application. I should be able to configure this client with .net core.
<bindings>
<customBinding>
<binding name="CustomBinding_1">
<security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport"
requireDerivedKeys="false" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
<issuedTokenParameters keyType="SymmetricKey" tokenType="">
<additionalRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
</trust:SecondaryParameters>
</additionalRequestParameters>
<issuer address="https://...../Services/Issuer.svc/IWSTrust13"
binding="ws2007HttpBinding" bindingConfiguration="https://....../Services/Issuer.svc/IWSTrust13" />
<issuerMetadata address="https://...../Services/Issuer.svc/mex" />
</issuedTokenParameters>
<localClientSettings cacheCookies="true" detectReplays="false"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Default" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="false" />
</binding>
</customBinding>
<ws2007HttpBinding>
<binding name="https://....../Services/Issuer.svc/IWSTrust13"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<endpoint address="https://....../Services/RoutingService.svc"
binding="customBinding" bindingConfiguration="CustomBinding_1"
contract="ServiceReference1.Service"
name="CustomBinding_1" />
+1
Hi,
Any update on this?
Microsoft MIM2016 Service uses WsHttpBinding, and currently it’s not possible to call this service from .Net Core as this binding is not supported.
Are there plans or work in progress to support this binding?
We now have the basics of WSHttpBinding which will be in our next release. It supports security mode TransportWithMessageCredentials. Currently the only credential types it supports are Certificate and Username. The foundation is now there to enable IssuedToken support which is what's needed to support WS-Fed.
@leoerlandsson, are there specific features of WSHttpBinding that you need? Also, are you sure that you need WSHttpBinding? The documentation I found here looks like you can define your own endpoints and the example is actually using BasicHttpBinding. If the new WSHttpBinding support isn't sufficient, it looks like you might be able to define a new endpoint on your MIM2016 service which will work with the features of WCF in .NET Core.
Thanks for looking into this @mconnew
The documentation you're referring to is a MIM Connector, and is another part of MIM.
The service I was referring to is the built in MIMService. Documentation can be found here (it's really still used, even internally in MIM, even though the documentation is deprecated).
More info:
Here
The internal MIM Service unfortunately is rather picky about the Bindings.
Nowadays, most people writing custom applications accessing the service probably use this project:
LithNet Resource Management Client
The bindings used there are these (see this code here)
:
WSHttpBinding: Client and Message Credential Type: Windows
WSHttpContextBinding (!)...: Message Security. Client and Message Credential Type: Windows
@leoerlandsson, I think what we have so far may work for you. The binding creation code in the GetWsHttpBinding method here is really odd. Security.Mode is being set to None, and then a bunch of security settings on Security.Transport and Security.Message are being set, but they will get ignored as the Mode is None. So if that is the binding which is used, then you should work with the latest code.
The binding returned by GetWsHttpContextBinding has multiple issues. First, it's using full Message security which we can't support due to missing dependencies. It's also using WSHttpContextBinding which exists for use with a WF. Basically it allows you to provide a context value when you start a new workflow and then come back at a later time (could be days) with a new channel instance but using the same context value to pick up the result of the workflow later. We aren't providing any workflow support in .NET Core.
@leoerlandsson, I also looked at the documentation. There's a WS-Trust endpoint but that's a provider of tokens, not an endpoint where you provide a token. You should be able to communicate with that using the Microsoft.IdentityModel packages for .NET Core but I'm not familiar enough with that package to tell you anything other than point you in the right direction.
@mconnew Thanks. I'll try it out with the LithNet package.
Unfortunately if I'm not mistaken I think that the MSFT MIM2016 (FIM) service requires full Message Security, but I'll give it a go.
I guess I'll have to build dotnet/wcf myself to get the latest additions?
does .net core 3,0 support WSHttpBinding now?
@leoerlandsson, I think what we have so far may work for you. The binding creation code in the
GetWsHttpBindingmethod here is really odd. Security.Mode is being set to None, and then a bunch of security settings on Security.Transport and Security.Message are being set, but they will get ignored as the Mode is None. So if that is the binding which is used, then you should work with the latest code.
The binding returned byGetWsHttpContextBindinghas multiple issues. First, it's using full Message security which we can't support due to missing dependencies. It's also using WSHttpContextBinding which exists for use with a WF. Basically it allows you to provide a context value when you start a new workflow and then come back at a later time (could be days) with a new channel instance but using the same context value to pick up the result of the workflow later. We aren't providing any workflow support in .NET Core.
Hi @leoerlandsson!
I came here looking to see if we could move the RMC client to .NET core yet. Did you have any luck with getting connected to the MIMService via .net core with its current capabilities?
Hi @ryannewington,
Unfortunately no, I did not get it working. There was still some missing components to get it working.
We did a workaround and installed the LithNet REST API instead (running on .NET Framework) and 'tunneled' the calls through that.
Br,
Leo
HI Guys, not sure if this is the right place, but do you guys support this issue in Dotnet core 3.0 yet?
https://stackoverflow.com/questions/47377043/wcf-service-credentials-in-asp-net-core-2-0
Thanks
J
Hello,
I am not sure if this is the right place to ask this, but I couldn't find a better one so here it goes:
Backstory: I have to call a 3rd-party (apparently Java) SOAP service that is using some more convoluted security than I would like. My project is on .NET Core 3.1 and is successfully calling a number of other SOAP services. _I am working off of the WSDL and an example request on this one._
From what I can tell from the WSDL, the binding is using a custom security policy, which seems to reference http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702
After doing some digging I found a question on StackOverflow that is pretty similar to mine, but has no answer. The headers I need to produce _(comparing these with my example request)_ are almost identical to the ones found at https://stackoverflow.com/questions/60675836/sign-soap-1-1-body-with-net-core-3-1 and the description there (about the AsymmetricBinding) matches what my WSDL says about the security policy.
Now I have a few questions:
Thank you.
Hi, what´s the current status of supporting WsFederationHttpBinding? If it´s available are there any examples of usage?
Hi, any updates for this thread, @iamjasonp and @mconnew?
@doorman02 , @yogitubadzin, this comment is probably the best starting point to understand the current state. We are working with some internal and external customers of WCF to get this working. As this is all new code, there are some scenarios which are taking a little bit of work to refine so we still have some bugs to shake out. I encourage you to give it a try as the sooner any bugs are reported, the sooner they can be addressed.
@mconnew when dou you have deadline for full release 4.8.0?
@mconnew Do you have any example of using certificates for WsTrustTokenParameters or related classes? We need use this now.
@yogitubadzin, 4.8.0 should be going RTM at the same time as .NET 5 is released, although we're still only requiring .netstandard 2.0 so we will work on all supported versions of .NET Core and you won't need to upgrade to .NET 5 to use it.
As for how to use certificates, if you look at the sample in the linked comment, there's an issuer binding. This is the binding used to communicate with your STS (usually ADFS server but doesn't need to be) when it's getting the WS-Trust token to talk to your actual service.. So you should just be able to configure the issuer binding to use certificates and set the client certificate on your channel factory client credentials. You didn't specify if you are using certificate with transport security or if you are using TransportWithMessageCredentials. Your issuer binding might also be WSHttpBinding and not the 2007 variant. You should be able to work this out from your existing binding. If you can't, post your existing binding and I'll try my best to help you. If could be as simple as using that sample with this change:
c#
var issuerBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
issuerBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
issuerBinding.Security.Message.EstablishSecurityContext = false;
Do you have a replacement for WSTrustChannelFactory and CreateChannelWithIssuedToken method in general on ChannelFactory?
https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.security.wstrustchannelfactory?view=netframework-4.8
.NET Framework Code
var factory = new WSTrustChannelFactory(
new IssuedTokenWSTrustBinding { SecurityMode = SecurityMode.TransportWithMessageCredential },
new EndpointAddress(new Uri(configuration.AdfsUrl)))
{
TrustVersion = TrustVersion.WSTrust13,
Credentials =
{
UseIdentityConfiguration = true,
SupportInteractive = false
}
};
var channel = factory.CreateChannelWithIssuedToken(securityToken);
Can CreateWsTrustRequest in WSTrustChannelSecurityTokenProvider be used? and do you have any example on how to use that class?
https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.federation.wstrustchannelsecuritytokenprovider.createwstrustrequest?view=dotnet-plat-ext-5.0
Hello, I missed this message as google put this to SPAM folder. Question
is to me and stil open?
wt., 2 lut 2021 o 17:05 EirÃkur Haraldsson @.*>
napisał(a):
Do you have a replacement for WSTrustChannelFactory and
CreateChannelWithIssuedToken method in general on ChannelFactory?.NET Framework Code
var factory = new WSTrustChannelFactory( new IssuedTokenWSTrustBinding {
SecurityMode = SecurityMode.TransportWithMessageCredential }, new
EndpointAddress(new Uri(configuration.AdfsUrl))) { TrustVersion =
TrustVersion.WSTrust13, Credentials = { UseIdentityConfiguration = true,
SupportInteractive = false } }; var channel =
factory.CreateChannelWithIssuedToken(securityToken);Can CreateWsTrustRequest in WSTrustChannelSecurityTokenProvider be used?
and do you have any example on how to use that class?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/wcf/issues/31#issuecomment-771743910, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AGS5DSXMZBRWBX4U4VEX6KLS5APGJANCNFSM4BETXH2Q
.
See this comment for how to do this.
You can try this.
https://www.nuget.org/packages/WsSecurityCore/
You can get the response as XmlNodeList or Xml full string and convert to response your class use XmlSerializer.
@mconnew Do we currently have support for Security - WSS SOAP Message Security UsernameToken Profile 1.1 with PasswordText type? even if it's in the preview versions?
If so could you please provide an example on how to configure it's binding?
@mconnew Do we currently have support for
Security - WSS SOAP Message Security UsernameToken Profile 1.1withPasswordTexttype? even if it's in the preview versions?If so could you please provide an example on how to configure it's binding?
WS Security not supported yet . You can try configure XML soap header for WsSecurity and send request .
Check this repo for example code : https://github.com/tayfunuyar/WsSecurityCore
@tayfunuyar With this Nuget package, I would still have to worry about creating the request body (envelope) and converting the response into a model class, which both are the only reason I'm considering the use of WCF
We do support a subset of message security. We don't support signing or encrypting the message itself, but we do support the token authentication part of it, but we only support the UsernameToken Profile 1.0. The difference between 1.0 and 1.1 is that 1.0 doesn't really obfuscate the password and 1.1 hashes it (and specifies the hash algorithm). The reason why this couldn't be done in WCF on .NET Framework is because on the service side the authentication was being done against Windows authentication which needed the plain text password. This code base doesn't need to be concerned with server side code, so in theory it should be easy enough to add support.
But this is something you can actually do yourself. There's quite a few boiler plate classes you need to create, but nothing really very complicated. First, you need to make a class derived from ClientCredentials and override the CreateSecurityTokenManager() method. You will need to return your own implementation of SecurityTokenManager which wraps the one returned by calling base.CreateSecurityTokenManager(). When SecurityTokenManager.CreateSecurityTokenSerializer you will return your own implementation of SecurityTokenSerializer. You can skip implementing any of the reading code as it's only used on the consuming side (ie server). You implement the abstract methods. CanWriteTokenCore, you check the token type and return true is it's the username security token. You don't need to worry about writing any key identifiers or key identifier clauses, our existing implementation just throws on those methods anyway. The only thing other than CanWriteTokenCore you need to implement is WriteTokenCore. Although it's in a different class, the current implementation can be seen here. From memory (it's been a few years since I looked at the spec), the differences are some minor namespace changes, the password is a hash of the password, and there was an extra element specifying the hash algorithm being used.
You will either need to use reflection to get the username/password from the UsernameSecurityToken, or provide your own SecurityTokenProvider which returns your own implementation.
Now that I've explained how to do it yourself, I found an implementation someone else has done and published in a blog post here. I only had a cursory look, but it looks like it should work. It has more in it than you need/will work on Core, so you can strip out the unnecessary code.
@mconnew Thank you so much for the guide.
But there's something that also interest me in what you said there, we do support UsernameToken Profile 1.0 ?
Is it out of the box? I couldn't get 1.0 to work on Core except with the help of these blog posts here and here.
What It's basically is that we create a bunch of boilerplate classes as well, it's simply creating your own MessageHeader class that would become the desired header format and adding that header into the your own implementation of BeforeSendRequest method in an implementation of IClientMessageInspector that gets added by another implementation of IEndpointBehavior
It works for 1.0 in Net Core but it also requires boilerplate code, do we have an out-of-the-box solution now like some certain binder settings?
You probably just want to use BasicHttpBinding with security mode TransportWithMessageCredential. Then set BasicHttpBinding.Security.Message.ClientCredentialType to BasicHttpMessageCredentialType.UserName. If you need any of the other WS-* specs like secure conversation, then you would need either WSHttpBinding or WS2007HttpBinding.
@mconnew I've tried it but it did not create a Security tag in the envelope's headers tag
I'm assuming it instead created a BASIC Http request header? I'm only assuming as the IClientMessageInspector.BeforeSendRequest Message object does not show actual headers sent in the HTTP request (?)
This is the configuration I've used
Note: The System.ServiceModel.Security nuget package version is 4.9.0-preview1.21224.1
var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
var client = new MyServiceClient(binding, endpoint);
client.ClientCredentials.UserName.UserName = username;
client.ClientCredentials.UserName.Password = password;
Since the Security envelope header wasn't there, my server did not accept the request and returned a fault thus WCF threw the following exception message.
Security processor was unable to find a security header in the message.
This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties.
This can occur if the service is configured for security and the client is not using security.
It will be there. Message inspectors don't run at the transport end of the stack where you would see the header, they run at the top where only the message body and basic headers are populated.
It's possible that the wrong security version is being used. A security header with the wrong name space is as good as no security header. Do you have an example of the expected security header? It might just need the MessageSecurityVersion to be set to something different.
This is the Expected security header tag
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>myUsername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">myPassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
I am not sure what does the header that WCF should be sending here should look like (and I'm fairly new to OASIS standards) but if it's the standard http header
key: Authentication value: Basic base64Encoded(username:password) then I'm sure my server doesn't accept that.
I can only call the server from a client, I do not have access to how it's internals work.
That is exactly the header I would expect to be emitted by WCF when using BasicHttpBinding. Can you use Fiddler to capture the request headers that WCF is sending and see what security header is being sent?
@mconnew Ok, so after investigating with fiddler, something interesting showed up.
Apparently the configurations I've mentioned above here sends the credentials inside the envelope headers as a Security tag and not as a Basic HTTP header, but even though the security tag is sent in the body in the end, It does not show in the IClientMessageInspector.BeforeSendRequest, It's inserted at a later step internally I assume.
nonetheless, since the security tag is created, the server responds successfully !
and even using the generated envelope captured by fiddler in something like postman makes the server responds successfully.
But still WCF throws the exception the moment the server returns it's response, could this be an internal bug? or maybe does WCF expects a certain header in the server response?
I've thought perhaps the issue is due to the preview version so I downgraded into the stable 4.8.1 but still the same behavior occurs
The Http headers that are sent are:
Cache-Control, SOAPAction, Request-Id, Accept-Encoding, Content-Type ,Content-Length
The generated envelope header is something as follows:
<s:Header>
<h:MyAppHeaders xmlns:h="http://xmlns.myServer.com/apps/myApp/" xmlns="http://xmlns.myServer.com/apps/myApp/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2021-05-16T12:56:09.980Z</u:Created>
<u:Expires>2021-05-16T13:01:09.980Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-ba03e9f6-8cb2-435d-bf84-c90026f59a56-1">
<o:Username>myUsername</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">myPassword</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
Oh, I think the problem is the server isn't responding with a security header. It's supposed to by the spec, but some implementations don't. There is a workaround, but I'm not going to have time to post it until Tuesday. It is mentioned elsewhere in another issue. Search for EnableUnsecuredResponse and you should find it.
@mconnew No need, You've helped me more than enough, thank you for your support on this project.
For those who look find similar issue Here's the Issue #3653 comment here that has the workaround.
So basically If one has a server that uses UsernameToken Profile 1.0 for security AND the server does not return a security header on the response, then there are two options here:
Either inject the header manually in the request and not tell binder to expect a security header in response (not specifying BasicHttpSecurityMode.TransportWithMessageCredential)
Or tell the binder to expect the header and inject an empty security header in the response in order to avoid the exception.
Both workarounds require boilerplate classes, I think I will stick to the request injection as it seem less boilerplate and more flexible workaround until the EnableUnsecureResponse binder flag is fully supported on Net Core, then I'd switch to the fully supported approach.
Hi Guys,
I am also facing the same issue and tried multiple work around to work but didn't succeeded.
Is there any latest release related to wshttpbinding support in .net core?
Thanks
Most helpful comment
@roncain @iamjasonp @mconnew Any news on this?