How to setup selfhosted https WCF service with embedded certificates on client and server? - https

Im creating a simple WCF service for receiving crash reports.
The service will run self-hosted as a console program and must run without any installation of certificates.
Security-wise i need to ensure that the data send by the client is only send to our server and that the data is not intercepted. From the server point of view i would also like to ensure that the connecting client is using a specific certificate (embedded in the client assembly) to discourage abuse of the service.
I have created a single self-signed certificate and plan to embed the .cer (containing the public part of the certificate) in the client assembly and embed the PFX containing the certificate with the private key into the service host program assembly. (I was led to believe by this that i could use a single certificate).
My problem is that no matter how is setup this up i get the following error:
"An error occurred while making the HTTP request to https://localhost:8080/errorservice. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server."
There shouldnt be a mismatch between the bindings, as they are created using the same code:
public static BasicHttpBinding CreateStreamingBinding() {
BasicHttpBinding streamBinding = new BasicHttpBinding();
streamBinding.TransferMode = TransferMode.StreamedRequest;
streamBinding.MaxReceivedMessageSize = long.MaxValue;
streamBinding.Security = new BasicHttpSecurity
{
Transport = new HttpTransportSecurity
{
ClientCredentialType = HttpClientCredentialType.None,
ProxyCredentialType =HttpProxyCredentialType.None
},
Mode = BasicHttpSecurityMode.Transport,
};
streamBinding.MaxBufferSize = int.MaxValue;
streamBinding.MessageEncoding = WSMessageEncoding.Mtom;
streamBinding.SendTimeout = new TimeSpan( 1, 0, 0, 0, 0 );
streamBinding.ReceiveTimeout = new TimeSpan( 1, 0, 0, 0, 0 );
return streamBinding;
}
On the client the code to create service is setup like this (the certificate location is just for testing):
protected ErrorReportingServiceClient CreateClient() {
X509Certificate2 cert = new X509Certificate2( #"C:\certs\reporting.cer" );
EndpointAddress endpointAddress = new EndpointAddress( new Uri( ReportingServiceUri ));
ErrorReportingServiceClient client = new ErrorReportingServiceClient( CreateStreamingBinding(), endpointAddress );
client.ClientCredentials.ServiceCertificate.DefaultCertificate = cert;
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
client.ClientCredentials.ClientCertificate.Certificate = cert;
return client;
}
On the service side the setup is as follows:
X509Certificate2 cert = new X509Certificate2( #"C:\certs\reporting.pfx", <password>);
BasicHttpBinding basicHttpBinding = CreateStreamingBinding();
host.Credentials.ClientCertificate.Certificate = cert;
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host.Credentials.ServiceCertificate.Certificate = cert;
host.AddServiceEndpoint( contractType, basicHttpBinding, baseAddress );
Any help on how to setup this correctly would be greatly appreciated.

The question was answered on the MSDN forums:
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/14f44296-5e3d-4df5-8cc4-a185415852b7

Related

Security token validation between Identity Server 4 and 3

I am trying to use a IdS4 server on .Net Core 2.0 with an IdS3 webforms client on .Net45.
As I login via the client I get this exception on the client browser.
[SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 2,
Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0x6B7ACC520305BFDB4F7252DAEB2177CC091FAAE1),
Clause[1] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
',
token: '{"alg":"RS256","kid":"6B7ACC520305BFDB4F7252DAEB2177CC091FAAE1","typ":"JWT",
"x5t":"a3rMUgMFv9tPclLa6yF3zAkfquE"}.{"nbf":1517303703,"exp":1517304003,
"iss":"http://localhost:5000","aud":"webforms","nonce":"636529004845229500.Mjg4YmMxMGEtZjk2MC00YWY5LWJiNTQtYmU0Njg0MDIwYTFhNzczN2Q1ZGMtN2YxYy00NGJmLWJhNzItNTM1ZDc0OTMyNzBj",
"iat":1517303703,"c_hash":"6Sty4gdTWGo4nEo0V_VSVQ","sid":"17936a127b0267d2588646052c4447c6",
"sub":"6498d093-8dc3-4d69-988e-3914d564f4d0","auth_time":1517303700,
"idp":"local","amr":["pwd"]}'.]
I first got this exception without Clause[0] and thought it was because the two samples I was using have different certificates embedded within them.
My attempt to fix this involved creating a new certificate following this guide.
In IdS4 Startup I have
services.AddIdentityServer()
.AddSigningCredential(GetSigningCredential())
and
private X509Certificate2 GetSigningCredential()
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySerialNumber, "3506fe4f69dc22b340e9c2af500d4659", false);
store.Close();
return certs[0];
}
With the clients secret set to the X509 thumbprint.
This seems to be working. On the IdS3 client I cannot find a way to validate the security token, I assume this would be done by validating the certificate?
If anybody could help me understand my issue better that would be great, I cannot find any useful documentation or examples relating to my case so pretty much anything would be helpful.
Thanks in advance.
Turns out I was trying to validate in the wrong places. All i had to do was point to the certificate in the clients Startup.cs.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Configuration = new OpenIdConnectConfiguration()
{
// Other Stuff...
SigningTokens = { new X509SecurityToken(GetX509Certificate2()) },
// More Stuff...
Where GetX509Certificate2() is:
private X509Certificate2 GetX509Certificate2()
{
var store = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
return cert = store.Certificates.Find(X509FindType.FindByThumbprint, "**thumbprint**", false)[0];
}

Xamarin .Net Core HttpClientHandler Method Not Implemented(VS for Mac)

I am writing a .net core(Standard 1.6) library that connects to my WebAPI. The WebApi requires a client certificate.
The .net core library is something being called from a Xamarin iOS app.
I cannot for the life of me send an HTTP request with a Client Certificate header.
I can use the library and post to the API with a client certificate from Visual Studio 2017 on a windows machine.
When I move the same project into my Xamarin iOS app using VS for Mac I get:
"Method Not Implemented" when setting the SslProtocol or adding the client certificate:
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2(certificate));
Relevant libraries:
using System.Net;
using System.Net.Http;
using System.Security;
using System.Security.Cryptography.X509Certificates;
Any help would be greatly appreciated.
Alright, this took me quite a while but i was able to send a client certificate in a web request to use for client auth on our server.
First, as awesome as Xamarin and .netCore are, they are missing alot of the methods .net developers are used to. I was not able to build a crossplatform request that would work on both Android and ios such as the HttpWebRequest.
For ios, i created a custom class that inherits from:NSUrlConnectionDataDelegate
I then override the:
public override void WillSendRequestForAuthenticationChallenge(NSUrlConnection
connection, NSUrlAuthenticationChallenge challenge)
{
byte[] cert = System.IO.File.ReadAllBytes("clientCertificate.pfx");
NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certPassword");
challenge.Sender.UseCredential(credential, challenge);
}
I then created a class that returns the credential:
//cert is a byte array of a .pfx file included in the resource file
//iSecurity Custom class
NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certpassword");
public static NSUrlCredential ImportPK12File(byte[] fileBytes, string passPhrase)
{
var cert = new X509Certificate2(fileBytes, passPhrase);
var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(passPhrase), SecImportExport.Passphrase);
NSDictionary[] importStatus;
SecStatusCode statusCode = SecImportExport.ImportPkcs12(fileBytes, options, out importStatus);
if(statusCode != SecStatusCode.Success){
throw new Exception("Error importing certificate. ");
}
NSObject obj = importStatus[0]["trust"];
IntPtr secTrustRef = obj.Handle;
var identityHandle = importStatus[0][SecImportExport.Identity];
var identity = new SecIdentity(identityHandle.Handle);
var certificate = new SecCertificate(cert.GetRawCertData());
SecCertificate[] certificates = { certificate };
return NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);
}
You may also be able to override this method and send the creds:
public override void ReceivedAuthenticationChallenge(NSUrlConnection connection, NSUrlAuthenticationChallenge challenge)
{
base.ReceivedAuthenticationChallenge(connection, challenge);
}
And i may move it to there but in order to fire this off you create the delegate of your class that inherits from :NSUrlConnectionDataDelegate
and add this to your connection. Any request fired through this connection will override the method and pass the certificate.

NativeMessageHandler Giving "Unauthorized" result on PostAsync

I am using ModernHTTPClient in my application to access a Secure ReST Service.
Server is configured with TLS1.2.
Whenever i try to hit the service with valid user credential, i gets the below error.
"Unauthorized"
"System.TypeInitializationException: The type initializer for
'System.Net.HttpVersion' threw an exception."
Below is the code which i used
NativeMessageHandler handler = new NativeMessageHandler(false, false);
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.EnableUntrustedCertificates();
handler.Credentials = oNwCred;
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
using (var oClient = new HttpClient(handler))
{
//Set Timeout
oClient.Timeout = new TimeSpan(0, C_TIME_OUT, 0);
oClient.DefaultRequestHeaders.Accept.Clear();
var oContent = new StringContent(szRequestJson, Encoding.UTF8, C_CONTENT_TYPE);
return await oClient.PostAsync(szUrl, oContent);
}
Server is configured with self signed certificate.
I have tried the code from Both PCL and from Droid project as well.
Thank you in advance for your help.
Regards
Vips

how to load OAuth certificate in dot net core

we are implementing the new application in dot net core, in the part we need to use open id authentication with our SecureAuth server. I am unable to figure out how to load the certificate into OAuthOptions.
here is my code to use OAuth
var cert = new X509Certificate2(Path.Combine(env.ContentRootPath, "/Connect.cer"));
var saOptions = new OAuthOptions
{
AuthenticationScheme = "ACR Connect",
ClientId = Configuration["AppSettings:ConnectSettings:ClientID"],
ClientSecret = Configuration["AppSettings:ConnectSettings:ClientSecret"],
TokenEndpoint = Configuration["AppSettings:ConnectSettings:CallbackPath"],
CallbackPath = Configuration["AppSettings:ConnectSettings:TokenEndpoint"],
AuthorizationEndpoint = Configuration["AppSettings:ConnectSettings:TokenEndpoint"],
UserInformationEndpoint = Configuration["AppSettings:ConnectSettings:UserInformationEndpoint"],
ClaimsIssuer = Configuration["AppSettings:ConnectSettings:ClaimsIssuer"],
};
app.UseOAuthAuthentication(saOptions);
When we are implementing in MVC5 we are pretty much sure about syntax, but How to do in MVC6(Dot Net Core 1.0).

Exporting exchange mails to Excel using lotusscript agent or Java agent or Javascript language

i want to export mails on exchnage server (subject line and body content) to Excel using lotusscript agent or Java agent or Javascript language. How can I acheive this? Any idea, suggestion or sample code is appreciable.
After doing reasearch found code to download mails from POP3 server. I used below code but got stuck at var oServer = new ActiveXObject("EAGetMailObj.MailServer"); with error - "Automation server can't create object". Then I put the host url in trusted sites and enabled active x control settings of IE, but then also getting the same error. Any idea, why?
The following code demonstrates how to receive email from a POP3 mail account. This sample downloads emails from POP3 server and deletes the email after the email is retrieved.
Code:
MailServerPop3 = 0;
MailServerImap4 = 1;
try
{
var oServer = new ActiveXObject("EAGetMailObj.MailServer");
// please change the server, user, password to yours
oServer.Server = "pop3.adminsystem.com"
oServer.Protocol = MailServerPop3;
oServer.User = "testx";
oServer.Password = "testpassword";
// If your server requires SSL connection,
// Please add the following codes.
oServer.SSLConnection = true;
oServer.Port = 995;
var oClient = new ActiveXObject("EAGetMailObj.MailClient");
oClient.LicenseCode = "TryIt";
// Connect POP3 server.
oClient.Connect(oServer);
var infos = new VBArray(oClient.GetMailInfos()).toArray();
for (var i = 0; i < infos.length; i++) {
var info = infos[i];
// Receive email from POP3 server
var oMail = oClient.GetMail(info);
// Save email to local disk
oMail.SaveAs("d:\\" + i + "_test.eml", true);
// Mark email as deleted on server.
oClient.Delete(info);
}
// Quit and pure emails marked as deleted from POP3 server.
oClient.Quit
}
catch( err )
{
WScript.Echo( err.description );
}
You can use Java and the Exchange Web Services API Java implementation at http://archive.msdn.microsoft.com/ewsjavaapi

Resources