HttpWebRequest Client Certificate not working in IIS - iis

I'm trying to create a WCF application hosted in IIS. This WCF App will call a third party website to download a CSV file. Third party website has provided a certificate to authenticate the WCF call. My development environment is,
-OS: Windows 2008R2
-Tools: Visual Studio 2010 (.Net 4.x)
During development I've no problem to make the calls using a HttpWebRequest, but after I deploy the same thing in IIS, it gives me the following error, even if I run the Visual Studio 2010 using IIS as dev server,
"\r\nCertificate information doesn't match login, connection denied."
The certificate during installation requires a password. I've installed it in "My User account" and "Computer account". It is also installed in IE. In all the installation it is installed in "Trusted Root Certification Authorities". But, still I'm getting the error message. I've given my code snippet below,
X509Certificate2 xc = new X509Certificate2(CertPath, GetCertificatePassword());
HttpWebRequest wc = (HttpWebRequest)WebRequest.Create(QryUrl);
wc.ClientCertificates.Add(xc);
Stream str = wc.GetResponse().GetResponseStream();
If someone can provide me any information, would be nice, thanks again,

This is just a guess: check that the user account that IIS runs under has access to the private key associated with the certificate.
If you use the MMC Certificates snap-in, select the certificate and then right-click -> All Tasks -> Manage Private Keys, and from there if you don't see the user account of IIS listed, you can add it there by clicking Add, and then in the dialog that comes up if for example you run IIS as Network Service, type "network service" (with the space) and click Check Names and then when you are back to Manage Private Keys you can set the security access.
I believe you only need to allow Read access to use the private key for a TLS connection.
You can set the access to the private key whether installed in Local Computer or Current User, but IIS won't have access to your Current User unless it runs as your user account.
Also, if it is a client certificate with a private key it almost certainly should go in the Personal store, and not in Trusted Root Certification Authorities. So try Local Computer, Personal, and give access to the private key to the account that IIS (or the application) runs under.

Related

Blazor Hosted WebAssembly application with Identity Server fails in production

I am developping a Hosted Blazor WebAssembly application with Identity Server. It works perfectly in my development environment, but fails in a production environment.
To try and find the reason, I went back to the templates supplied with Visual Studio and got the same issue. So here are the details to replicate.
In VS 2022 (currently 17.4.4), create a new project.
Select the Blazor WebAssembly App template.
Select .NET 7.0 framework.
Select Individual Accounts for the Authentication type and check the ASP.NET Core Hosted option.
The application runs fine locally.
Before publishing it:
Create a self signed certificate with PowerShell and export it to a certificate.pfx file.
Edit the IdentityServer section in appsettings.json:
"IdentityServer": {
"key": {
"Type": "File",
"FilePath": "certificate.pfx",
"Password": "password"
},
"Clients": {
"BlazorWasmIdentityHosted.Client": {
"Profile": "IdentityServerSPA"
}
}
}
In Visual Studio, modify the certificate.pfx properties so that it is copied when publishing.
Modify the web.config file in the publish folder so that exception pages are displayed in the browser:
<aspNetCore ...>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
I then get an error page as soon as I request the home page
CryptographicException: File not found.
System.Security.Cryptography.X509Certificates.CertificatePal.FilterPFXStore(ReadOnlySpan<byte> rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
InvalidOperationException: There was an error loading the certificate. Either the password is incorrect or the process does not have permisions to store the key in the Keyset 'DefaultKeySet'
Microsoft.AspNetCore.ApiAuthorization.IdentityServer.SigningKeysLoader.LoadFromFile(string path, string password, X509KeyStorageFlags keyStorageFlags)
As I am deploying to a hosting provider where I don't have a direct access to IIS, I suspect that I don't have the rights to add an item to a certificate store.
I tried deploying to IIS on my local machine, it runs fine.
So, my question is: Is there any other way to manage a signing key in this specific configuration: IIS on a shared hosting provider (managed with Plesk)?
The Microsoft documentation gives details about deploying to Azure (here), but I didn't find much on deploying to IIS in my situation.
Edited:
I finally think the issue was with lack of access rights for the IIS user on the hosting provider. Not sure if that can be fixed (depends on the provider), so I finally moved to Azure. Setting and deploying need some care, but at least it's well documented by Microsoft, and now it works for me.
I recently came across an article discussing common issues when dealing with X509Certificate2 object creation, handling private key material in application code. One of the common problems is certificate and private key handling inside .NET applications. Most of the problems for these use cases occur in web applications when certificate lookup/instantiation fails. For example, certificate reading works on a developer machine, but fails when the application is deployed to production. I want to share the content of this article with you, in order to avoid the article link from expiring, I quoted the content from the article in the answer, hoping to bring you some help.
There are two common deployment models for application certificates:
Persistent - certificate is installed in certificate store which is independent to application (such as Windows Certificate Store). The installed certificate is shared with any other application that runs under same security account.
In-app - The certificate is either embedded in the app itself or
stored as an external protected file. This includes PFX files,
keychains, Azure Key Vault, and many others.
Pros and Cons of the Persistent Deployment Model:
The benefit of the persistent deployment model is simplified
certificate management, which can be easily installed and managed
using external mechanisms such as certificate autoenrollment and
Certificate Lifecycle Manager (CLM). CLM makes it easy to manage
certificates in the certificate store without having to update or
redeploy applications every time certificates are renewed.
Of course the downside of this mode is that there is no certificate
isolation/protection between processes. When the application is
deleted, the certificate is not deleted and remains on the system.
Even if the certificate is deleted from persistent storage (Windows
certificate store), the private key is not necessarily deleted: case
of accidental deletion of user certificates. Another process under the
same security account or a computer administrator can easily access
the certificate and its private key material.
The in-app deployment model has the opposite characteristics of the persistent model.
The benefit of the in-app model is better certificate and private key
security. Private keys may not be shared with other applications
running under the same security account, and computer administrators
may be prevented from accessing private key material. The application
loads the certificate into memory only when necessary, and then
unloads the certificate and private key.
There is a parameter called password which is known only to authorized
applications and which provides private key isolation between
processes. Applications that do not know the password can’t access the
certificate and private key. Although the code looks secure, in fact
it is not in the current way. The problem is with default behavior of
the X509Certificate2 constructors that import certificate from PFX.
Using default constructors, such as X509Certificate2(String, String),
X509Certificate2(String, SecureString), X509Certificate2(Byte[],
String), X509Certificate2(Byte[], SecureString), private key is
silently copied and persisted on a system, this will introduce
security holes in working code. Any simple application/script can use
FileSystemWatcher to detect key file creation and immediately create a
copy of the key file.
To avoid this bad behavior, a constructor with three parameters must
be used. The third parameter is the X509KeyStorageFlags enumeration
type.
DefaultKeySet — copies private key to default store. It can be specified in PFX properties (user key set or machine key set). If none
specified in PFX, user key set is used. This is something you don’t
want to use, because it persists the key on a disc. And if PFX
specifies Machine Key Set and application doesn’t have local
administrator/system permissions, the call will fail with exception.
UserKeySet — forces private key copy to user profile regardless what is specified in PFX properties.
MachineKeySet — forces private key copy to local system profile. If application doesn’t have local administrator/system permissions,
the call will immediately fail.
Exportable — copies private key to default key set (see rules above) and makes private key exportable. This makes zero sense,
because application doesn’t need to have an access to private key
material. If the application require this, the application is simply
wrong. Instead, the application must deal with handles provided by
operating system. Nothing else.
UserProtected — this flag enables private key strong protection. This doesn’t work with any non-interactive applications, because raise
UI popups and require user input. And in web/background applications
the popup is raised in background sessions you cannot access.
PersistKeySet — is similar to DefaultKeySet with the exception that private key permanently persists on a disk even if you explicitly
release all handles.
EphemeralKeySet — the only flag that doesn’t copy private key material on a disk and the only that makes sense, because it does
exactly what we need — temporarily load the key from PFX and unload
when finished.
When loading a certificate with a private key from PFX or Azure Key Vault, you >should use the EphemeralKeySet enumeration value.
For more detailed content, you can get an in-depth understanding through the article link provided above.

Xero partner certificate installation under IIS

I am having problems correctly installing the OAuth certificate required for Xero partner integration on IIS 7.5 on Windows Server 2008 R2. There used to be guidance from Xero on this at http://developer.xero.com/documentation/advanced-docs/using-partner-applications-with-iis/ but the page just 404s now.
I've installed the certificate to the Trusted Root Certifications Store as per the prior Xero advice, and my code can retrieve the certificate (using its serial number); but when I try to access the private key, I get a CryptographicException: Keyset does not exist error, which other SO posts suggest is a permissions error (my application runs under a dedicated service account), but all those posts assume the certificate is installed in the personal certificate store - the TRC store does not give me the option of granting permissions to the service accounts or any other account.
I think that page used to give information about installing an Entrust client certificate as partner applications in the past needed to use one.
You don't need to use a client certificate these days and partners should instead direct their traffic to "https://api.xero.com" instead of "https://api-partner.network.xero.com".
You also don't need to install your oAuth certificate as that certificate is used only for signing your requests.

MVC Application call a web service with client certificate

I have a MVC 4.0 application with a web service as reference. The web service is installed on third party remote server will SSL. Also the web service requires client certificate authentication. I installed the certificate that issued by the 3rd party to our test server on Personal store, Trusted Root Certificate Authorities and Third-Party Root Certificate Authorities. Same to my local computer. The application is able to access the remote server and get response on my local development server, but always failed on our test server. Our test server is win 2003 and IIS 6.0. The error I got is "Client Certificate Required". It looks like the remote server either reject or cannot take the certificate we pass.
Here is my code:
var svc = new webservcie();
svc.ClientCertificates.Add(X509Certificate.CreateFromCertFile("c:\clientcert.cer"));
svc.Credentials = new NetworkCredential(username, password);
svc.url = "https://www.thirdparty.com/WMServices";
svc.givemedata()
I have tried many ways to fix this issue, but cannot. I think the issue is that our test server is not able to access the client certification. I read an article about grant Networkservice access to the certificate, but not sure if it is right or not.
Could someone please help me out? Thanks!
I found more detail error from server application event log:
Failed auto update retrieval of third-party root list sequence number from: http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootseq.txt with error: This network connection does not exist.
Thanks!

IIS Web Deploy - ERROR_USER_NOT_ADMIN

I have a server which is part of a domain. When I publish a web application from Visual Studio with a domain user everything is ok. But when I try to publish with a local machine user (not part of a domain) I get ERROR_USER_NOT_ADMIN. Both users are in Administrators group. I tried specifying user as username, .\username and machinename\username but it's not working. Is there anything else I should do to be able to publish with a local machine user?
I received this error when I published with an incorrect password.
Not the best answer in the world but I post this to point out that an incorrect password does indeed return this exact error though you would never know it when you read the error message.
This error can also be received when deploying ASP.NET Core application with Visual Studio 2015. In order to fix the problem in this case, add the following lines in the .pubxml file:
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<AuthType>NTLM</AuthType>
You can't do that, server you aim to publish in to needs an authorized domain account to allow access to your Visual Studio publishing service. Local accounts are specific to your local machine regardless whether they are administrator logins. They are just local admin login not domain admin logins.
Get your administrator to set up a domain user (don't use domain admin accounts this is a security risk) for publishing purposes or use your current domain user account

Certificates problem with Sharepoint

I'm contacting a web service using a certificate stored in Machine and in user space "myUser".
When I contact the web service impersonating "myUser" from a win application all works well.
But when I contact this using Sharepoint context (I have only 1 frontend) I have only sometimes the following error:
Could not establish trust relationship
for the SSL/TLS secure channel with
authority 'server.host:4443'
I verified that the web service is invoked using user "myUser" as expected but in Sharepoint context sometimes this method crashes.
I don't know what can be the problem. It seems related to Sharepoint/ASP.NET security context but all seems to be ok. Any suggestion?
I think that the only sometimes is the important point here.
Since it works most of the time it is actually setup and configured ok.
The machine that you are sending the certificate to must be able to validate the certificate. My guess is that something is going wrong sometimes. Things that could cause this are:
a network problem, firewall ...
AD server down (I am assuming a self issued certificate)
AD server too busy
Check the event logs of your AD and Sharepoint server.
Have you granted access to the certificate for the asp.net worker process under which SharePoint is running?
In Windows 2008, you need to open the certificates mmc (Start -> Run -> MMC -> File -> Add/Remove SnapIn -> Certificates. Be sure to select "Computer Account" when prompted for how certificates will be managed. Locate the certificate, right-click on it, select "All Tasks". There should be an option in there that allows you to manage permissions to the certificate. You will need to grant read access to the account under which the application pool for SharePoint is running.
Note: if you are running Windows Server 2003, you will need to use winhttpcertcfg.exe to configure certificate permissions.
Try this:
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
Before you make any calls.

Resources