Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identityserver4 - Hosting in IIS

How to host ASPNET CORE APP with IdentityServer4 in IIS. The app is running fine from localhost but not as a web application setup in IIS.

For Example,

http://localhost:5000/connect/token is working but http://example.com/myauthapp/connect/token is not reachable - returning 500 - internal server error when tried from a console app using identity model or via postman. I am able to login to the app using web browser but not thru a console app or postman.

Further Troubleshoot and I find the below.

An unhandled exception has occurred: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.
System.InvalidOperationException: IDX10638: Cannot created the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.
   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
   at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

How can I solve this issue?

like image 303
Arun Avatar asked Feb 20 '17 17:02

Arun


2 Answers

As Arun noted in his comment, the certificate has to be installed on the server.

1 . To test this on localhost first, make sure you are using "AddSigningCredential" not "AddTemporarySigningCredential".

services.AddIdentityServer()
                    .AddSigningCredential(new X509Certificate2(Path.Combine(_environment.ContentRootPath, "certs", "IdentityServer4Auth.pfx")));
                    //.AddTemporarySigningCredential()
 ;
  1. Create the certificate in your project (create certs folder), running this in visual studio command:

"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\makecert" -n "CN=IdentityServer4Auth" -a sha256 -sv IdentityServer4Auth.pvk -r IdentityServer4Auth.cer -b 01/01/2017 -e 01/01/2025

"C:\Program Files (x86)\Windows Kits\8.1\bin\x64\pvk2pfx" -pvk IdentityServer4Auth.pvk -spc IdentityServer4Auth.cer -pfx IdentityServer4Auth.pfx

  1. Test on localhost

  2. If successful, deploy to iis server , install the certificate on the server by double clicking on it, and test.

  3. Make sure the application pool "load user profile" is set to true :

    • Go to IIS Manager
    • Go to the application pool instance
    • Click advanced settings
    • Under Process model, set Load User Profile to true
  4. Restart IIS

  5. If this fails with a 500, like with me (and there is no logs to help you out), try this. To fix this recreate the certificate on the server the same way as in step 2 in the certs folder . double click the cert to install. You might have to install the developer kit if you dont have visual studio installed: https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk

like image 139
David Smit Avatar answered Nov 01 '22 18:11

David Smit


A little background first, on why it is working on your Local Development computer and not running under IIS on a QA or Production Environment. If you are using Temporary Signing Credential when adding the service Identity Server 4 like so,

services.AddIdentityServer().AddTemporarySigningCredential();

Then you have to make sure the "User" that the "Process" is running as has a Private Key available for ID4 to create a Temporary Certificate. This is why the error message is

SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures. Key: Microsoft.IdentityModel.Tokens.RsaSecurityKey.

enter image description here

In the case of Windows, this private key is generated by Windows automatically and can be found at the folder %APPDATA%\Microsoft\Crypto\RSA of the User or C:\Users\Username\AppData\Roaming\Microsoft\Crypto\RSA. The reason why this Private Key is missing is perhaps because the User that your Process is running as has never logged onto that Computer.

The likely SOLUTION in that case is to log in once as the User that will be running the Process on that Server. It is quite common for the Private Key directory to be missing if your Application Pool within IIS runs as a "non-service" user with very High Privileges and that user has never interactively logged onto the Server itself. This also explains why "localhost" works on your development computer, while running on a Production or QA Server may not.

More information on how and where Windows creates the Private Key for a User can be found here in this link Microsoft Key Storage and Retrieval. Also, it is recommended as mentioned by David Smit to explicitly specify a Private Key file, instead of using Temporary Signing Credentials. That is the cleaner solution if you are allowed to make code changes.

services.AddIdentityServer()
                    .AddSigningCredential(new X509Certificate2("C:\Certs\IdentityServer4PrivateKeyFile.pfx")));
like image 33
CodeCowboyOrg Avatar answered Nov 01 '22 17:11

CodeCowboyOrg