WCF WebService cannot get PrivateKey from certificate - c#

I already created a WCF Service that is hosted in IIS, I've created an CA makecert and one certificate for autenticating the service using HTTPS. With this certificate I have make work it. Now I'm trying to use the Message Security in the service.
In the web.configI have the next code:
<serviceCredentials>
<serviceCertificate findValue="192.168.1.230" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" />
</clientCertificate>
</serviceCredentials>
When I try to view the Web Service through an explorer like Chrome, I'm receiving the next error System.Security.Cryptography.CryptographicException: KeySet does not exists. I check the inner exception and this is what I see
[CryptographicException: El conjunto de claves no existe]
System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +5368074
System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle) +138
System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() +221
System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey() +516
System.ServiceModel.Security.SecurityUtils.GetKeyContainerInfo(X509Certificate2 certificate) +45
System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +76
[ArgumentException: Puede que el certificado 'CN=192.168.1.230' no tenga un clave privada capaz de intercambiar claves, o que el proceso no tenga permisos de acceso a la clave privada. Vea la excepción interna para obtener información detallada.]
System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +16947147
System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement) +190
System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirement) +50
System.ServiceModel.Security.AsymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout) +930
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +79
System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(TimeSpan timeout) +397
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +375
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +249
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +125
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +901
[ServiceActivationException: El servicio '/WebFrontITAS.svc' no se puede activar debido a una excepción durante la compilación. El mensaje de la excepción es: Puede que el certificado 'CN=192.168.1.230' no tenga un clave privada capaz de intercambiar claves, o que el proceso no tenga permisos de acceso a la clave privada. Vea la excepción interna para obtener información detallada..]
System.Runtime.AsyncResult.End(IAsyncResult result) +622882
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +196075
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +282
I googled a lot about this, but I have not found anything usefull. When I try to get the private key using FindPrivateKey.exe it fails and give me the next error No certificates with key '192.168.1.230' found in the store.
I'm not sure if the problem is with the cert or with the configuration of WCF.

Besides changing the user another way to solve this issue is give the App Pool the WCF service is running under permissions to read the private key.
Open the certificate store for your system and find your certificate, from there choose Manage Private Keys
Inside the security setting add the app pool your WCF service is running under by adding the name IIS AppPool\App_Pool_Name_Here (if you are on a domain be sure the location is set to the computer not the domain)
Then check the box for Read permissions and your app should start being able to read your certificate.
NOTE: I have encountered a bug where depending on how you imported your certificate the program will still not work correctly, I have found this usually happens if you used IIS to import the certificate. If you remove the certificate and re-add it from inside the Certificates manager using the wizard built in to the manager it will often fix the issue.

I already solved this issue, the problem was the autentication of the AppPool of IIS, It was using a network credential that does not have permission to access the cert store, When I change the Autentification to a LocalUser, the problem was solved.

Related

Use MassTransit for Azure Service Bus with a 'send' shared access policy [duplicate]

I spent some days testing MassTransit 3.1.2 to see if we can use it with Azure Service Bus in our applications.
I made a sample with two console applications using MassTransit.AzureServiceBus (3.1.2) : one publisher and one suscriber.
It works well. When I start the applications, the entities (queues, topic, subscriptions) are created automatically on my namespace on Azure.
That's nice when you are testing thing but in production, I don't want the application to be allowed to create entities. We want to create them upfront.
To try that, I thought It was a good idea to connect to the bus using SAS policy with "Send" or "Listen" permissions only (before I was using a namespace policy with "Manage" permission).
Now I'm struggling on this point, I can't get it to work, I'm always getting 401 errors Manage claim is required for this operation if I don't use a policy with "Manage" permissions.
I tried setting the policy on the namespace or the entities directly without success.
After that I analyzed the stack trace exception (useless part omitted with [...]) :
System.UnauthorizedAccessException: Le serveur distant a retourné une erreur : (401) Non autorisé. Manage claim is required for this operation. TrackingId:2ca420e3-aac6-467c-bacb-6e051dbc3e39_G47,TimeStamp:1/29/2016 11:20:41 PM ---> System.Net.WebException: Le serveur distant a retourné une erreur : (401) Non autorisé.
à System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.GetAsyncResult`1.<GetAsyncSteps>b__3c(GetAsyncResult`1 thisPtr, IAsyncResult r)
à Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
--- Fin de la trace de la pile d'exception interne ---
Server stack trace:
Exception rethrown at [0]:
à Microsoft.ServiceBus.Common.ExceptionDispatcher.Throw(Exception exception)
à Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
à Microsoft.ServiceBus.Common.AsyncResult`1.End(IAsyncResult asyncResult)
à Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.EndGet[TEntityDescription](IAsyncResult asyncResult, String[]& resourceNames)
à Microsoft.ServiceBus.NamespaceManager.EndGetQueue(IAsyncResult result)
à System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.<CreateQueueSafeAsync>d__1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.Pipeline.PrepareReceiveQueueFilter.<Send>d__5.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.AzureServiceBusTransport.ServiceBusReceiveTransport.<>c__DisplayClass12_0.<<Receiver>b__0>d.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
[...]
à MassTransit.Internals.Extensions.TaskExtensions.<WithCancellation>d__0`1.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception
[...]
à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
à MassTransit.MassTransitBus.<StartAsync>d__30.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
à System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
à MassTransit.Util.TaskUtil.Await[T](Func`1 taskFactory, CancellationToken cancellationToken)
à MassTransit.MassTransitBus.MassTransit.IBusControl.Start()
I found out that the line with MassTransit.AzureServiceBusTransport.NamespaceManagerExtensions.CreateQueueSafeAsync to be really interesting because I was able to look at the MassTransit source code to see what it was doing. I saw that it was doing some calls using the NamespaceManager to get the queue or topic.
Since this class is named NamespaceManager, I thought that would mean you need "Manage" permission anyway.
To try that, I made a basic console application using only the Azure SDK to make some calls to the NamespaceManager using a policy with only Listen or Send permissions : I got 401 errors on all the calls I tried. Adding Manage permission worked.
I didn't find anything about this assumption in the Azure documentation or maybe I missed something.
Final question :
Is there a way to use MassTransit on Azure Service Bus with a Send or Listen policy only ? Did I miss something and I'm heading the wrong way ?
Because MassTransit is responsible for managing the topology of the service bus namespace, including creating topics and queues as well as creating and binding subscriptions, the manage permission is required.
While you might think it's a great idea to create everything in production manually and leave that permission off your application, you will always spend time figuring out why things are broken in production and frustrate your engineers. I speak from experience on this one -- it's why we require the permission.
There are also auto-delete queues created for bus management, which again requires the manage permission.
UPDATE: Manage is still required, however, you might be able to get around it. If you can create topics, queues, and subscriptions in advance, and you configure MassTransit to not create topics, queues, or subscriptions, and probably to not publish faults (unless you're going to create those topics as well), and not use error or skipped queues.
For example, this configuration would basically limit the use of MassTransit to a queue only:
var bus = Bus.Factory.CreateUsingAzureServiceBus(cfg =>
{
cfg.Host(...);
cfg.ReceiveEndpoint("existing-queue", e =>
{
e.PublishFaults = false;
e.ConfigureConsumeTopology = false;
e.ConfigureDeadLetterQueueErrorTransport();
e.ConfigureDeadLetterQueueDeadLetterTransport();
e.Consumer(...);
});
});
Messages sent to the queue directly (destinationAddress of queue:existing-queue) would be consumed by the receive endpoint, and error/skipped messages would be moved to the Azure dead-letter queue. You could only call publish if the topic name matching the message type exists (or you could use topic:existing-topic-name as the destination address).

Can't deploy to FTP with port 22 in Visual Studio

I am trying to publish a project in Visual Studio 2019, pointing to port 22 (since I will use a linux environment later)
I followed the steps of:
https://es.stackoverflow.com/questions/239559/error-al-compilar-proyecto-aspx-en-visual-studio and
https://www.a2hosting.com/kb/a2-hosting-products/windows-hosting/publish-a-site-from-visual-studio-using-ftps
So to summarize:
start in administrator mode
enable the FTP and IIS options
I put in front of my URL both ftps and 990
I ping the IP and it is active and without problems
but I still get the same error that I can't connect to the server
Attached the error log
11/12/2020 13:36:22
System.AggregateException: Se han producido uno o varios errores. ---> System.Exception: Error de compilación. Compruebe la ventana de salida para obtener más detalles.
--- Fin del seguimiento de la pila de la excepción interna ---
en System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
en System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
en Microsoft.WebTools.Publish.PublishService.VsWebProjectPublish.<>c__DisplayClass43_0.<PublishAsync>b__3()
en System.Threading.Tasks.Task`1.InnerInvoke()
en System.Threading.Tasks.Task.Execute()
--- Fin del seguimiento de la pila de la ubicación anterior donde se produjo la excepción ---
en System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
en System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
en Microsoft.Publish.Framework.ViewModel.ProfileSelectorViewModel.<RunPublishTaskAsync>d__213.MoveNext()
---> (Nº de excepción interna 0) System.Exception: Error de compilación. Compruebe la ventana de salida para obtener más detalles.<---
System.Exception: Error de compilación. Compruebe la ventana de salida para obtener más detalles.
Port 22 is SFTP, not FTP(S). The FTPS and SFTP are two completely different protocols. You cannot use the FTP protocol to connect to an SFTP server.
I believe that Visual Studio does not support the SFTP.
See Visual Studio Publish Website Using SCP/SFTP

Problem deploying ASP.NET CORE 3.1 MVC app to azure

The main problem is the database. I have a local database created with Microsoft SQL Managment Studio and is the one I want my app to use as I have a register/login/credential system. I have created a SQL Server in azure with its own database with the idea of just copying the data from the local database to the new one. I have also created an app service plan and an app service. I have downloaded its publishing profile to use it on the upload. Then I edit its settings and add the
Server=tcp:csptest06.database.windows.net,1433;Initial Catalog=csptestDB06;Persist Security Info=False;User ID=JoseAdmin;Password=******;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
on both the default connection and entity framework inmigration, then just publish it. At first it couldnt connect because I didnt add my ip but after that it just gave me this error:
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error Web deployment task failed. (Error durante la ejecución del script de la base de datos. El error ocurrió entre las siguientes líneas del script: "326" y "342". El registro detallado podría tener más información acerca del error. El comando comenzaba con lo siguiente:
"IF NOT EXISTS(SELECT * FROM [__EFMigrationsHisto"
There is already an object named 'TUsers' in the database. http://go.microsoft.com/fwlink/?LinkId=178587 Obtenga más información en: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_SQL_EXECUTION_FAILURE.)
Failed to publish the database. This can happen if the remote database cannot run the script. Try modifying the database scripts, or disabling database publishing in the Package/Publish Web properties page. If the script failed due to database tables already exist, try dropping existing database objects before creating new ones. For more information on doing these options from Visual Studio, see http://go.microsoft.com/fwlink/?LinkId=179181.
Error details:
Error durante la ejecución del script de la base de datos. El error ocurrió entre las siguientes líneas del script: "326" y "342". El registro detallado podría tener más información acerca del error. El comando comenzaba con lo siguiente:
"IF NOT EXISTS(SELECT * FROM [__EFMigrationsHisto"
There is already an object named 'TUsers' in the database. http://go.microsoft.com/fwlink/?LinkId=178587 Obtenga más información en: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_SQL_EXECUTION_FAILURE.
There is already an object named 'TUsers' in the database.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.Web.Deployment.DBStatementInfo.Execute(DbConnection connection, DbTransaction transaction, DeploymentBaseContext baseContext, Int32 timeout) CSP0308 0
Any idea on how to fix this? im relatively new to programming so please dont fear on going step by step on your ideas
Fixed it and managed to publish it successfully. If anyone is wondering this is how I did it:
Followed this video:How to upload your local database to AZURE
From that on I connected from visual studio to the database hosted in azure. Deleted a migration I had that dupped all the tables and from there I copied the connection string and published it.

Error in Xamarin.Forms Release with Lottie/CacheStrategy

I am getting an error, when I try to deploy my android apk xamarin forms or when I compile release. it has to do with the library lottie cachestrategy
error follows.
Mono.Linker.MarkException: Error processing method: 'System.Void >XF.Material.Droid.Renderers.MaterialCircularLoadingViewRenderer::OnElementChanged>(Xamarin.Forms.Platform.Android.ElementChangedEventArgs`1)' in assembly: 'XF.Material.Droid.dll' ---> >Mono.Cecil.ResolutionException: Failed to resolve Com.Airbnb.Lottie.LottieAnimationView/CacheStrategy >Com.Airbnb.Lottie.LottieAnimationView/CacheStrategy::get_Strong()
en Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
en Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
en Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
en Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
en Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
en Mono.Linker.Steps.MarkStep.ProcessQueue()
--- Fin del seguimiento de la pila de la excepción interna ---
en Mono.Linker.Steps.MarkStep.ProcessQueue()
en Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue()
en Mono.Linker.Steps.MarkStep.Process()
en MonoDroid.Tuner.MonoDroidMarkStep.Process(LinkContext context)
en Mono.Linker.Pipeline.Process(LinkContext context)
en MonoDroid.Tuner.Linker.Process(LinkerOptions options, ILogger logger, LinkContext& context)
en Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res)
en Xamarin.Android.Tasks.LinkAssemblies.Execute()
en Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
en Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext() Amis.Reportes.Android
and option Linking is "Link SDK assemblies only"

Unable to modify server by programming since SQL Server 2014

I have a c# program which connects to a server SQL to create a data base.
everything was working with Microsoft SQL Server 2008 but with Microsoft SQL Server 2014 i am facing some issues.
My code is :
Server server = new Server(new ServerConnection(instanceName));
server.ConnectionContext.LoginSecure = true;
server.ConnectionContext.Connect();
server.Settings.LoginMode = mode;
server.Alter();
And the Alter command throw the exception : "Fail to modify for server"
I have tried this https://support.microsoft.com/en-us/kb/956013 but it doesn't work.
EDIT1:
Exception (sorry I use french version of Visual) :
Message : Échec de Modifier pour Serveur « .\SQLEXPRESS ».
=> Fail to Modify for Server « .\SQLEXPRESS »
GetType() : Microsoft.SqlServer.Management.Smo.FailedOperationException
StackTrace : à Microsoft.SqlServer.Management.Smo.SqlSmoObject.AlterImpl()
InnerException : Microsoft.SqlServer.Management.Common.ExecutionFailureException: Une exception s'est produite lors de l'exécution d'une instruction ou d'un lot Transact-SQL. ---> System.Data.SqlClient.SqlException: The EXECUTE permission was denied on the object 'xp_instance_regwrite', database 'mssqlsystemresource', schema 'sys'.
à Microsoft.SqlServer.Management.Common.ConnectionManager.ExecuteTSql(ExecuteTSqlAction action, Object execObject, DataSet fillDataSet, Boolean catchException)
à Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
--- Fin de la trace de la pile d'exception interne ---
à Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
à Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)
à Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQuery(StringCollection queries)
à Microsoft.SqlServer.Management.Smo.SqlSmoObject.ExecuteNonQuery(StringCollection queries, Boolean includeDbContext)
à Microsoft.SqlServer.Management.Smo.SqlSmoObject.AlterImplFinish(StringCollection alterQuery, ScriptingPreferences sp)
à Microsoft.SqlServer.Management.Smo.SqlSmoObject.AlterImplWorker()
à Microsoft.SqlServer.Management.Smo.SqlSmoObject.AlterImpl()
Data : System.Collections.ListDictionaryInternal
Source : Microsoft.SqlServer.Smo

Categories

Resources