Webapi selfhost start HTTPS troubleshooter and cannot return the results correctly

Source: Internet
Author: User

Objective

Say again to demand, before for in Selfhost in need nested page and operation for abnormal demand, this back normal demand, the client now added HTTPS, the eldest brother came to say that Webapi can't access, this is what situation, I went to try, it is really this situation, do not know how to start Ah, Finally, in order to solve this problem, the long journey of exploration began, hoping to give a little inspiration and help for children's shoes that need to start HTTPS under Selfhost.

Topic Introduction

When the client sends a request to send but to look at the Google console display of the message to the effect is not mixed use that is the client for HTTPS, then WEBAPI can not be HTTP, is estimated to be a security problem, so the problem is more clear, only need to change the WEBAPI to HTTPS, It is obviously not possible to modify the address in selfhost directly to HTTPS. You have to use the certificate and open the corresponding port, since we have analyzed, then we solve the problem of Webapi start HTTPS. Start thinking about a free certificate to apply for, but because the WEBAPI is installed in the local Windows service and IP is not fixed, so the free certificate is no longer desirable, can only create a certificate to solve this problem. But I almost never contacted the certificate, know nothing about it, where to start, this long process began.

Resolve Selfhost Start HTTPS

Search the garden for the answer to the self-created certificate, basically either IIS, or WCF creates the certificate, but there is a little bit of thinking that provides the commands needed to create the certificate, starting with a little thought. I'm going to be shocked when I see one of the following commands, so what's the deal, so easy!

First attempt
HTTP add urlacl Url=https://+:p ort/user= ""

It turns out that this is just a reserved item for the URL.

Second attempt

We create a certificate with the VS Development command

The first step:

" Cn=webapi CA " //2050 -R

Note: the last-R of the command is not missing,-R is the identity of the create self-created certificate, or "Error:file not found" occurs when the private key is created with PVK2PFX. Error Code = 0x80070002) "

The result becomes as follows:

Step Two:

When you open an MMC to import the certificate that you created into a trusted certification authority, it becomes the following:

Step Three:

Get the thumbprint of the certificate and listen to the IP and port, by the following command:

HTTP add sslcert ipport=0.0. 0.0:8084 certhash=996645bab7169f2afd7599a696da2586862843c6 appid={41992502-e5d4-  4794-bb01-d4a7414480cc}

Everything is so perfect, finally look at the results, let me again disappointed:

At this point I have been on the brink of collapse, the answer to search for this reason, can not solve, at this time only to seek the almighty StackOverflow, see this answer is surprising:

Http://stackoverflow.com/questions/13076915/ssl-certificate-add-failed-when-binding-to-port

The main idea is that the self-created certificate will be imported into the "personal" certificate through MMC and then dragged into the personal certificate to see it.

The result is still this error, when I come back to see all the answers above, the following answer is simply to save me, this problem troubled me one day, I am extremely excited. Please look at this sentence:

You can easily check if your certificate have private a key as so:--- mmc certificates local machine personal . Look at the icon of the certificate-it must has key sign on the icon.

Also in the personal certificate in the local calculation, see whether there is a small key in the upper left corner of the certificate, this key is the private key, we also have to create the private key to line, with the following command.

Fourth Step:

Create the private key of the certificate

PVK2PFX-PVK developmentca.pvk-spc developmentca.cer-pfx developmentssl.pfx-po Password

And then we'll run the third step. The success is as follows:

We then run the program https:localhost:8084 to accept the results as follows:

So what should be the solution to this problem? Some people may have to say, click on the following high-level direct go to it, although this style is acceptable, but in our project, is through the "device" to access the WEBAPI, based on this is absolutely not possible, so must kill it. After all my attempts, I found that I could do it. We will MAKECERT-SV d:developmentca.pvk-n "cn=webapi CA" d:developmentca.cer-b 09 /-E /2050 -R in CN modified to localhost is issued to localhost but can , repetitive actions are no longer demonstrated, and the final result for the demo is as follows:

Note: If you still find that the certificate is invalid when you arrive here, please do the following, resources from a video demo from YouTube during the search, see below:

The final "Allow identifiers for protected content (which may need to be restarted)" will be demonstrated.

Here about the Webapi selfhost start https problem basically solved more than half, for me, for you may have over, but in the actual scene is not complete. When the test found that the above will not request to WEBAPI, at this time in the Google console but the following error:

:: Net_error_response

Third attempt

Resolves that the client cannot access localhost.

Think of the solution, the search data thought is a cross-domain problem, the result is not, in the client side is to use the WEBAPI local IP to access, so consider whether localhost does not. Ben wanted to steal a little lazy, in the hosts folder to map localhost, the result is still not, the access address becomes: https:192.168.3.6:8084 finally finished.

Here also completed 90%, the individual is not very satisfied, thinking that although there is a little bit of the past, that is the first to import the certificate into the "trusted authority", but also need to import the certificate through the MMC personal certificate, which I am unable to accept, I continue to start the exploration journey. Import the certificate into the personal certificate of the MMC in the form of code.

Fourth attempt

Import the certificate into the personal certificate in code form, instead of looking for a solution through an MMC import.

Try creating an Access HTTPS certificate by running the following code:

varFileName = AppDomain.CurrentDomain.BaseDirectory +"developmentssl.pfx"; varCert =NewX509Certificate2 (FileName,"Password"); varstore =NewX509store (storename.my, storelocation.localmachine); Store.            Open (Openflags.readwrite); Store.            ADD (CERT); Store.            Close (); Process P=NewProcess (); p.StartInfo.FileName="Netsh.exe"; P.startinfo.arguments=string. Format ("http Add sslcert ipport=0.0.0.0:8084 certhash={0} appid={1}", cert. Getcerthashstring (),"{"+"41992502-e5d4-4794-bb01-d4a7414480cc"+"}"); P.startinfo.useshellexecute=false; P.startinfo.redirectstandardoutput=true;            P.start (); P.close ();

At this point, use the following command to see if HTTPS is turned on:

netsh http show sslcert

The result does not see the display open port, at this time think perhaps is not enough authority? Then run the identity of the initiating process as "administrator" and add the following code to the boot process above:

" runas ";

There is no impact at this point, the ports that need to be opened are still feuds, the Webapi is hosted in the Windows service, we are using batch processing, so try to take a look at the batch deployment, and see the results of the demo:

Results cannot be returned correctly

When everything is ready, the front end reacts with the returned results incorrectly and cannot be resolved, cue unravelling, continue fighting, shown in the console as follows:

This result is unheard of, actually appeared a " K__backingfield " field, after the query related data to arrive: in Webapi the default is to use Json.NET in the " Defaultcontractresolver "To parse the object, which is caused by adding a" Serializable "object to the parsed object, for example:

    [Serializable]    publicclass  person    {        publicint  getset;}    }

The default attribute should be omitted by removing the "Serializable" attribute or by adding the following statement to the global configuration to correctly display the desired result:

            Config. Formatters.JsonFormatter.SerializerSettings.ContractResolver =  newtrue };

"Recommendation": whether or not to add the above serialization attributes, it is recommended to add the above ignored default serialization attributes in the global configuration.

Resources:

Http://stackoverflow.com/questions/29701891/k-backingfield-remove-in-c-sharp-seen-via-swashbuckle-swagger

Http://stackoverflow.com/questions/35259333/jsonmediatypeformatter-formatting-with-k-backingfield

Is it all over? Task is completed, in order to have a more in-depth understanding of the certificate, we will expand the certificate knowledge.

Certificate Knowledge Extension

How do two of servers use certificates to trust each other? Please see:

In the example, the administrator establishes a trust relationship between the servers by exchanging the thumbprint in the public key between the two parties. For the certificate above we have also demonstrated in. NET is implemented by " X509Certificate2 ", let's take a look at this class.

1th: Differences between certificates and PKCS #12/pfx files

X509Certificate2 This class has two properties that are public key and private key (private key), and whether the private key can be exported when we import the certificate, the typical certificate in Windows is terminated with the extension. cer, and of course it does not contain the private key.

Here we can export a certificate like this:

            var"developmentca.cer";             var New X509Certificate2 (fileName);            File.writeallbytes (@ "d:hello.cer", cert. Export (X509contenttype.cert));

Sometimes we need to export the private key, at this time the private key and extension. PFX ends in another file, which can be exported as follows:

File.writeallbytes ("hello.pfx", cert. Export (X509CONTENTTYPE.PKCS12, (string)null));

Hello.pfx is actually a pkcs#12 file, it can be used as a separate file to store the need to encrypt objects, do the general purpose is to use X509CERTIFICATE2 to store the private key, for more information, please refer to:

Https://en.wikipedia.org/wiki/PKCS_12

2nd: Certificate Store

In this case, we have also demonstrated that the console certificate Manager that we open through MMC can import the current user or the local computer account, and if you just want to see the current user certificate, you can open it through certmgr.msc. So how do you do it in code form? As follows:

var New X509store (storename.my, Storelocation.currentuser), store. Open (openflags.readwrite); store. ADD (certificate); store. Close ();

The certificate can be imported into the current user through Storelocation.currentuser, mapped to the current user's personal certificate by storename.my, or by the enumeration above in other institutions in the native computer account. This will be added in the following registry

Hkey_current_user\software\microsoft\systemcertificates

or through the desktop path

C:\Users\username\AppData\Roaming\Microsoft\SystemCertificates\My\Certificates

The following path is, of course, the local calculation:

Hkey_local_machine\software\microsoft\systemcertificates
3rd: Understanding the private key

We have described above that the certificate is not with the private key, private key when used as a single file to use, then the private key exactly where to store it? We give the following code:

 var  fileName = AppDomain.CurrentDomain.BaseDirectory +  " developmentssl.pfx  "  ;  var  cert = new  X509Certificate2 ( Filename, "  ", X509keystorageflags.machinekeyset | X509keystorageflags.persistkeyset | X509keystorageflags.persistkeyset |             x509keystorageflags.exportable);  var  store = new   X509store (storename.my, storelocation.localmachine); Store.            Open (Openflags.readwrite); Store.            ADD (CERT); Store. Close ();  

The private key is now stored in the following registry:

Hkey_local_machine\software\microsoft\systemcertificates\my\keys

If we make the following changes, change the MachineKeySet to Userkeyset:

 var  fileName = AppDomain.CurrentDomain.BaseDirectory +  " developmentssl.pfx  "  ;  var  cert = new  X509Certificate2 ( Filename, "  ", X509keystorageflags.userkeyset | X509keystorageflags.persistkeyset | X509keystorageflags.persistkeyset |             x509keystorageflags.exportable);  var  store = new   X509store (storename.my, storelocation.localmachine); Store.            Open (Openflags.readwrite); Store.            ADD (CERT); Store. Close ();  

This will be stored in the following places:

C:\Users\username\AppData\Roaming\Microsoft\SystemCertificates\My\Keys\

There may be a problem when the certificate is imported and used by the local computer, but at this point the private key is in the personal User folder, and if the other account on the computer wants to access the private key, it may not have this permission or the private key.

A few notes on enumerating X509keystorageflags:

(1) Exportable: Specifies that it can be used to back up the private key when creating the certificate.

(2) Persistkeyset: When you create a certificate, you specify that it can be imported once and used more than once.

(3) Userkeyset: Specifies that it can be used in another account when creating a certificate.

(4) MachineKeySet: When you create a certificate, you specify that it may cause the other account to have no permissions or access to the private key, which does not exist.

4th: Be cautious when creating certificates

Carefully export the certificate using the byte array var certificate = new x509certificate2 (bytes) , the file is written to the Temp folder, At this point it is possible that the temporary folder will not be cleaned up effectively, causing the temporary folders to swell.

Tools Introduction

The following URL can be seen here through the MakeCert program to create a certificate has been deprecated (before PowerShell4.0 we can download MakeCert from creating a certificate).

Https://msdn.microsoft.com/library/windows/desktop/aa386968.aspx

The certificate created now can be made through PowerShell (although the system is in Windows 8 or Windows Server 2012 or Windows 8.1 or Windows Server R2), please see the following URL for more information about this command:

https://technet.microsoft.com/library/hh848633

It looks like it's hard, but actually more concise than the MakeCert command, let's take a look (switch to PowerShell).

(1) Use the following command to create a certificate and obtain its thumbprint

New-selfsignedcertificate-certstorelocation cert:\localmachine\my-dnsname localhost

Issued to localhost and saved to the "personal" certificate on the local computer, the results are as follows:

(2) When you need to export a certificate, you need to use a variable to save the password

" pa$ $w 0rd " -force-asplaintext

(3) Export PFX, specify the first step to get the thumbprint and the second step to save the password

Export-pfxcertificate-cert Cert:\localmachine\my\ce0976529b02de058c9cb2c0e64ad79dafb18cf4-filepath d:cert.pfx- Password $pwd

Summarize

This section to the end of this is completely, will be in the WEBAPI use process encountered in the problem to be described again, the whole of which spent three days, writing this blog spent a day, a long time did not sit to spend nearly a day of energy to write a blog, but indeed actually rose a lot of knowledge, If there is something wrong with the content of the article, welcome criticism, but also for the follow-up to other needs to use the children's shoes little pit is also worthwhile, here is very grateful to the park friends, "Magic Days Mans", encountered any difficulties in asking him to consult, thank him for his trouble and guidance, again expressed thanks. Here also in advance to wish you all the Park friends Happy National Day.

Resources

Http://stackoverflow.com/questions/29701891/k-backingfield-remove-in-c-sharp-seen-via-swashbuckle-swagger

Http://stackoverflow.com/questions/779228/the-parameter-is-incorrect-error-using-netsh-http-add-sslcert?answertab=votes

http://southworks.com/blog/2014/06/16/enabling-ssl-client-certificates-in-asp-net-web-api/

Http://stackoverflow.com/questions/28854466/makecert-exe-error

http://stackoverflow.com/questions/6307886/how-to-create-pfx-file-from-certificate-and-private-key/18704221#18704221

Http://paulstovell.com/blog/x509certificate2

Http://stackoverflow.com/questions/35259333/jsonmediatypeformatter-formatting-with-k-backingfield

Http://www.thewindowsclub.com/disable-insecure-content-warning-chrome

Http://windowsitpro.com/blog/creating-self-signed-certificates-powershell

Webapi selfhost start HTTPS troubleshooter and cannot return the results correctly

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.