I use 3rd party client library which internally communicates with server (somewhere in cloud) using WCF (I only can configure few key/value settings, the library creates all the WCF client proxy stack within its code).
If I use the library in WinForms or console application it works well, however calling the library API from within WebApi it ends up with error:
An exception of type 'System.ServiceModel.Security.MessageSecurityException' occurred in mscorlib.dll but was not handled in user code
Additional information: The Identity check failed for the outgoing message.
The remote endpoint did not provide a domain name system (DNS) claim and therefore did not satisfied DNS identity 'serverName'.
This may be caused by lack of DNS or CN name in the remote endpoint X.509 certificate's distinguished name.
Why there is a difference? The server side is the same, so does this mean the identity check is not performed when running in WinForms app? Or the identity check is performed differently when running in WebApi? How can I fix it?
I run the code from within VS2015, WebApi is hosted in IISExpress. The library uses NetTcpBinding with TransportWithMessageCredential and MessageCredentialType.UserName
Try adding this to your app.config file
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IdentityModel.DisableMultipleDNSEntriesInSANCertificate=true" />
</runtime>
</configuration>
From MSDN:
Starting with apps that target the .NET Framework 4.6.1, the X509CertificateClaimSet.FindClaims method will attempt to match the claimType argument with all the DNS entires in its SAN field.
Impact
This change only affects apps that target the .NET Framework 4.6.1.
For apps that target previous versions of the .NET Framework, the X509CertificateClaimSet.FindClaims method attempts to match the claimType argument only with the last the DNS entry.
Mitigation
If this change is undesirable, apps that target the .NET Framework 4.6.1 can opt out of it by adding the following configuration setting to the section of the app’s configuration file:
https://msdn.microsoft.com/en-us/library/mt620030%28v=vs.110%29.aspx
Related
We have 2 projects hosted on IIS: Blazor WebAssembly site and authorization web service.
Web service is hosted on Default Web Site, Blazor project as a separate site. Each has it's own app pool ('No managed code'). Both are .NET6 using EF Core. They do not reference each other.
Recently I updated packages in Blazor project to latest versions. After publishing that change our web serivce started throwing:
An unhandled exception has occurred while executing the request.
System.TypeInitializationException: The type initializer for 'Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder' threw an exception.
---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.EntityFrameworkCore.Abstractions, Version=6.0.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
File name: 'Microsoft.EntityFrameworkCore.Abstractions, Version=6.0.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder..cctor()
EntityFrameworkCore libraries on that web serivce are of version 6.0.5. Our Blazor site was moved to 6.0.6. How can one affect the other?
They are both published by Jenkins as self-contained without trimming, then copied to server.
Web service does not reference Microsoft.EntityFrameworkCore.Abstractions directly, but I can see it down the line of package refences for EF Core.
I can see the relevant library in the physical folder on server, it's of expected version 6.0.5.
Still, web server throws on any GET, with Swagger or via the Blazor site.
Tried so far:
Add rights for IIS_IUSRS for site and service folders
Changing app pool identity for web service
Add rights for app pool specific users for site and service folders
Enabling 32-bit app setting in IIS, it is not compatible with our apps
Checked that ASPNET user has rights to Temp folder just in case
The issue still occurs, on some days it all works without problems.
There are many reasons for this error, you can try below methods:
Restart the server to reload everything again, check if site works.
Change 'Enable 32-bit application' from false to true in the advanced settings of the application pool.
Change the identity of the AppPool that your app is using to NetworkService.
IIS > Application Pools > Select current app pool > Advance Settings > Identity.
Grant IIS_IUSRS full access to the Microsoft.EntityFrameworkCore.Abstractions.
Setting hosting model as OutOfProcess for the web service finally fixed the issue. Other solutions did not provide any lasting results.
It can be set in web.config:
<aspNetCore ... hostingModel="outofprocess">
In my VS solution, I created a console project, which I'm using as the client, and an empty project for the WCF service.
I then created the WCF service (created my contract and service type and manually constructed the app.config), and added a reference to the WCF service project in the client project.
However, when I called ServiceHost.Open() in the client, the endpoints weren't loading. I eventually determined that I needed to put all of the config information in the Client's app.config, rather than the service's app.config.
I'm not sure if this is normal, or if I'm doing something wrong. In the past, when I've used the WCF project template, this wasn't the case.
Yes, that is normal. Each .NET application (client, service, web site, etc.) has it's own configuration file. To be precise, there's a hierarchy of them, but the bottom end of that hierarchy is unique to the application.
This makes sense if you think about it -- the client would need to contact the service to ask for it's configuration, but it needs to know the endpoint information in order to even try to do that. So yes, the normal process is that client and service both have very similar information in their configuration files.
If you use Visual Studio's built-in tooling to do everything for you, it will automatically create and/or edit the configuration file for your client when you add a Service Reference to the project, copying from the metadata endpoint that WCF exposes for that purpose. Alternatively, you can use the WCF configuration editor tools to edit your client application.
Also, note that nothing actually enforces that your client and server have compatible settings; e.g. you can change the maximum sizes of many buffers/graphs/etc on one side, and not the other, and see some strange behavior. It's up to you to make sure both ends are working with mutually usable settings.
I have a set of WCF Services Hosted in IIS7. I'm in the process of moving the services to a different folder in order to start specifying version and environment in the URL. For example:
http://myserver/MyServices/ServiceA.svc
Becomes:
http://myserver/MyServices/QA/1.1.0/ServiceA.svc
I configured the new folder to be an application in IIS, and set it up to run under the same service app pool we've been using. That has all worked fine, I am able to navigate to my .svc URL and view the WSDL or open up the endpoint in wcf test client. However, when trying to consume the service I am getting the following error:
The identity check failed for the outgoing message. The expected identity is 'identity(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn)' for the 'http://myserver/MyServices/QA/1.1.0/ServiceA.svc' target endpoint.
When I check the WSDL output, I noticed that the identity section seemed to leave out the identity of the app pool, which it usually includes:
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Upn>myappuser#mydomain.local</Upn>
</Identity>
After trying to redeploy and reconfigure the app in IIS, I was able to get the identity to appear in the metadata for only some of the services. Other services still don't include it, which is even more strange than before. There are zero configuration differences between the original stack and the new stack in IIS as far as I can tell. What sorts of issues could I be running in to that would causes these types of identity issues?
The issue was caused by trying to nest the new service stack web application inside of the existing service stack web application. I think that may have caused some confusion for IIS when services in the sub-application were exposing endpoints to the same contracts that the root web application (although in theory this should work just fine). I simply had to move the new service stack into a separate folder structure. Once I did that, I had no problems getting the app pool identity to be exposed in the metadata.
Basically I separated the whole login registration and authentication of the Silverlight Business Application template into a WCF RIA Services class library. But I am not getting this remote server returned NotFound error.
I am supposed to use the SqlRoleProvider and SqlMembershipProvider to hook up the authentication context to my database, instead of the default express database.
I'm confused on the whole app.config and web.config thing. How do I know what goes where?
I would say nothing is impossible! There are more than one ways to dong things, all you need is to think about it.
See: http://www.codeproject.com/KB/macros/Config-Merge.aspx
Or you can use <connectionStrings configSource="App.Config"> in web.config
Here you are asking web.config to pick settings from another app.config in same directory.
Anything you want to have affect runtime behavior, or used at runtime must go into web.config. App.config doesn't get applied at runtime.
As such, things like connection strings, provider configuration etc. must all be placed in web.config. Unfortunately there is no VS mechanism to transfer/merge settings from app.config of a class library into a web project.
Caution, WCF noobie alert
I need to create a WCF client to query a non-WCF web service.
The web service is not a WCF service. Additionally, the web service requires a client authentication certificate. Now, I have the certificate, and can create a non-WCF client that works perfectly; I was able to 'Add Web Reference' and a certificate dialog box opened up to allow me to select the appropriate certificate, then went on to create the web reference. Trying to create a WCF client via 'Add Service Reference' is another story, it just fails with a 403 Access Denied error.
I have the WSDL for the service, and have run svcutil.exe on it, but am not sure how to proceed from there.
Thanks for any help!
I'm assuming that the service you are using is performing client SSL authentication.
Since add service reference is failing, you can use svcutil to generate the client from the WSDL file that you have. I think the syntax would be something like:
svcutil *.wsdl /l:C# /out:Reference.cs /config /s /ct:System.Collections.Generic.List`1 /ser:Auto /tcv:Version35 /n:*,<NameOfYourNamespaceHere> /edb
This will generate a file, Reference.cs, that contains the proxy classes to the service (you can give this file whatever name you want). Add this file to your project. A config file, output.config, will also be generated. You can add this configuration to your application configuration instead of typing it all in by hand.
Now you can follow this MSDN article on using Transport Security with Certificate Authentication. You can skip down to the client section where it shows how to attach the certificate to the request in code as well as in configuration.
I know this is the old question and it has been already solved but I would like to mention that Add service reference also works for WSDL files stored on disk. Marc has also mentioned it. Add service reference dialog accepts:
URL to WSDL
URL to Metadata exchange endpoint
Service URL where /mex is added internally
Any file path to WSDL file
So if you have WSDL and all need XSD files you can use Add service reference as well. The only tricky part is that Add service reference dialog doesn't have Browse button and that is the reason why this functionality is not well known.
Stupid question (maybe): could you connect to the service endpoint, present it with your credentials stored in the certificate, and then download the WSDL (and possibly XSD) from there? Or could it be the entity offering this service would be able to actually send you these files (or make them available for download)?
Once you have the WSDL (and XSD) file on disk, it should be easy enough to create WCF client for that (using either svcutil.exe or Add Service Reference) based on those files, and then configure the appropriate security for it.
Just a thought.... (worth $0.02?)
Marc
OK, bit of a work-around here (and I've no idea what is going on technically): I noticed that when you add a Web Reference, the certificate you have chosen is cached and automatically used the next time you add the Web Reference (I noticed because I'd chosen the wrong certificate). This caching seems to work across Web Reference and Service Reference so:
Add a Web Reference to the endpoint, choosing the certificate you wish to use
Remove this Web Reference
Add a Service Reference to the same endpoint and Visual Studio will use the same certificate you chose for the Web Reference
Worked on Visual Studio Community 2019, v16.7.7