How to access MongoDB using GSSAPI authentication mechanism? - c#

I am trying to connect to the MongoDB server through a ssl certificate using c#. I am getting a System.TimeoutException (A timeout occurred after 30000ms selecting a server using the CompositeServerSelector).
I started with connection via MongoClientSetting object. Here is the code:
MongoClientSettings settings = new MongoClientSettings();
settings.MaxConnectionLifeTime = new TimeSpan(12, 0, 0);
settings.UseSsl = true;
settings.VerifySslCertificate = false;
var cert = new X509Certificate2("mongoDBCAFile.cer");
settings.SslSettings = new SslSettings{
ClientCertificates = new[] { cert }
};
settings.Servers = new[]{
new MongoServerAddress("xyz1.intranet.companyname.com", 12345),
new MongoServerAddress("xyz2.intranet.companyname.com", 12345)
};
settings.ReplicaSetName = "replicaName";
var cred = MongoCredential.CreateGssapiCredential("username#intranet.companyname.com").WithMechanismProperty("SERVICE_NAME", "servicename");
settings.Credential = cred;
var client = new MongoClient(settings);
var database = client.GetDatabase("DatabaseName");
var collection = database.GetCollection<BsonDocument>("CollectionName");
//This is the place of error
var count1 = collection.CountDocuments(new BsonDocument());
I tried playing around with ConnectTimeout, SocketTimeout, and wTimeOut but the error was same.
I also tried doing the same thing using the connection string as mentioned here but I wouldn't figure out how to create a connection string with these many parameters.

Found the solution.
The issue was with authentication of the user with external server. MongoDB server was waiting for the clearance from this external server, but Because the authentication was never successfully, MongoDB always lead to System.TimeoutException.
Here is the fix code.
settings.ReplicaSetName = "replicaName";
SecureString pwd = new NetworkCredential("intranet/userName", "myPassword").securePassword;
var cred = MongoCredential.CreateGssapiCredential("username/intranet.companyname.com", pwd).WithMechanismProperty("SERVICE_NAME", "serviceName").WithMechanismProperty("CANONICALIZE_HOST_NAME", "true");
settings.Credentials = cred;

Related

My gRPC-Test Project just work on localhost

i have the following problem.
I created a gRpc Server(Console App .Net 4.7.2 - i cant do Net Core on Server Side because of Crystal Reports :() and a Client(WPF App .Net Core 3.1) and i can run it as long as Server and Client are on my machine (Windows 10). As far es i take my Server to another machine (windows Server 2016), it does not work anymore.
this is the RPC Exception:
Status(StatusCode="Unavailable", Detail="failed to connect to all
addresses",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{"created":"#1595508082.170000000","description":"Failed to pick
subchannel","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x64\src\core\ext\filters\client_channel\client_channel.cc","file_line":3948,"referenced_errors":[{"created":"#1595508082.170000000","description":"failed
to connect to all
addresses","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x64\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.cc","file_line":394,"grpc_status":14}]}")
i tried all variations. Here is my lastcode that works on localhost:
Server:
static void Main(string[] args)
{
var cacert = File.ReadAllText(#"root.crt");
var servercert = File.ReadAllText(#"server.crt");
var serverkey = File.ReadAllText(#"server.key");
var keypair = new KeyCertificatePair(servercert, serverkey);
var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair>() { keypair }, cacert, false);
// Build a server
var server = new Server
{
Services = { ReportService.BindService(new KKarteReportService()) },
Ports = { new ServerPort(Host, Port, sslCredentials) }
};
// Start server
server.Start();
Console.WriteLine("KKarteReport Server listening on port " + Port);
Console.WriteLine("Press any key to stop the server...");
Console.ReadKey();
server.ShutdownAsync().Wait();
}
Client
var cacert = File.ReadAllText(#"root.crt");
var clientcert = File.ReadAllText(#"client.crt");
var clientkey = File.ReadAllText(#"client.key");
var ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey));
var options = new List<ChannelOption> { new ChannelOption(ChannelOptions.SslTargetNameOverride, "MyServerHost") };
var channel = new Channel("12.20.18.11", 5001, ssl, options);
//var channel = new Channel("localhost", 5001, ssl, options);
//var channel = new Channel(url, ChannelCredentials.Insecure);
var client = new ReportService.ReportServiceClient(channel);
using var streamingCall = client.CreateAusschreibung(request);
await using var ms = new MemoryStream();
while (await streamingCall.ResponseStream.MoveNext())
{
ms.Write(streamingCall.ResponseStream.Current.FileChunk.ToByteArray());
}
What do i miss?
What does the ‘Host‘ variable contain on the server side? The issue might be a incorrect address binding, which prevents the service from being reachable from IP addresses other than localhost (127.0.0.1). Try entering 0.0.0.0 there.

Soap request using service reference

I am trying to call an external soap request but i keep getting the error below:
System.ServiceModel.FaultException: java.lang.NullPointerException
I can't figure out what is lacking here, i have check the wsdl and didn't find any parameters that are mandatory.
SoapService.queryWebServiceSoapPortClient client = new SoapService.queryWebServiceSoapPortClient();
client.ClientCredentials.UserName.UserName = "";
client.ClientCredentials.UserName.Password = "";
SoapService.qwsInput query1 = new SoapService.qwsInput();
SoapService.queryResponse response = new SoapService.queryResponse();
query1.pass = Password;
query1.queryId = queryId;
query1.qwsInputParams = "something";
query a = new query();
a.queryInput = query1;
try
{
response = client.query(a);
}
catch (Exception error) {
var b = error.ToString();
}
I eventually contacted the soap provider and they figure out the account i was using to connect to the soap service was not working for some reason. The above code works perfectly with the new account.

Is this why a WCF SSL Secure Channel is faulting?

I'm supporting a project where we recently needed to apply a series of upgrades to a newer version of the .Net Framework. This has largely succeeded but for one final component that's been around for a very long time.
Our client uses InfoPath templates to populate information for other users to consume. Everything the templates need comes from a WCF web service we host. We set the web service call up with the following code.
private WSHttpBinding CreateBinding()
{
var wsHttpBinding = new WSHttpBinding();
wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.BypassProxyOnLocal = false;
wsHttpBinding.TransactionFlow = false;
wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
wsHttpBinding.MaxBufferPoolSize = 524288;
wsHttpBinding.MaxReceivedMessageSize = 2147483647;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
wsHttpBinding.TextEncoding = Encoding.UTF8;
wsHttpBinding.UseDefaultWebProxy = true;
wsHttpBinding.AllowCookies = false;
wsHttpBinding.ReaderQuotas.MaxDepth = 32;
wsHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
wsHttpBinding.ReliableSession.Ordered = true;
wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReliableSession.Enabled = false;
wsHttpBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
wsHttpBinding.Security.Transport.Realm = string.Empty;
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttpBinding.Security.Message.NegotiateServiceCredential = false;
wsHttpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256;
return wsHttpBinding;
}
private EndpointAddress CreateEndPoint()
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = store.Certificates.Find(X509FindType.FindBySubjectName, "*.wildcard.address.foo", false)[0];
store.Close();
EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity(certificate);
string address = getWcfServiceUrl();
AddressHeader header = AddressHeader.CreateAddressHeader(address);
List<AddressHeader> headerList = new List<AddressHeader> { header };
Uri uri = new Uri(address);
var endpointAddress = new EndpointAddress(uri, identity, headerList.ToArray());
return endpointAddress;
}
}
This works fine and if we're testing it out, calls can be made successfully for all other intents and purposes. Except for one.
In one case we need to get information from a 3rd party resource. In that situation, our web service makes a separate call out to this 3rd party at an HTTPS address (passed in to the url parameter here:
private string requestURL(string url)
{
string toReturn = null;
Stream stream = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = httpMethod;
stream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
StreamReader reader = new StreamReader(stream);
toReturn = reader.ReadToEnd();
}
catch(Exception e)
{
throw new Exception("Error with that service please try again: " + e.Message, e);
}
finally
{
if(stream != null)
{
stream.Close();
}
}
return toReturn;
}
In this case, the following error is returned:
The request was aborted: Could not create SSL/TLS secure channel.
My suspicion is that we're setting up a very specific set of constraints around the SSL connection between our local client (i.e. InfoPath) and the web service but the call from that web service to the 3rd party is not set up with any constraints beyond simply calling over HTTPS.
What should I be looking out for in trying to fix this issue?
WCF IMHO is particular about configuration at both ends and asks for things like transport credential specifically in the back and forth. I suspect you have no control of how the security is managed at the third party and can't change it, but your generic method to call all web services won't work because the configuration doesn't match.

Accessing a bucket at the google S3 api

I am trying to read a bucket at storage.googleapis.com, using the Amazon Web Services .Net SDK in C#.
Can anyone provide a working example of a S3 endpoint Config setup for google, just using the Auth. key/secret pair and a bucket name? Or using any other method to get this working?
According to this tutorial this should be a simple matter, but I get all sorts of exceptions when trying to follow the instructions given. Here is an extract of my current attempt - which throws a TrustFailure exception:
The remote certificate is invalid.
AmazonS3Config conf = new AmazonS3Config();
// Set regionEndpoint to null, or else the serviceURL will be ignored
conf.RegionEndpoint = null;
conf.ServiceURL = "https://s3.storage.googleapis.com";
conf.UseHttp = false;
conf.AuthenticationRegion = null;
conf.UseAccelerateEndpoint = false;
conf.UseDualstackEndpoint = false;
AWSCredentials cred = new BasicAWSCredentials("GOOG3LFXXXXXXXXXXXXX", "BQ6VeMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
IAmazonS3 client = new AmazonS3Client(cred, conf);
GetBucketVersioningRequest request = new GetBucketVersioningRequest { BucketName = "hisbucket" };
GetBucketVersioningResponse response = client.GetBucketVersioning(request);
I finally got the .NET SDK to upload to Google Cloud Storage with:
AWSConfigsS3.UseSignatureVersion4 = false;
AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = "https://storage.googleapis.com";
config.SignatureVersion = "2";
AmazonS3Client client = new AmazonS3Client(accessKey, secretKey, config);
var transferUtilityConfig = new TransferUtilityConfig
{
ConcurrentServiceRequests = 1,
MinSizeBeforePartUpload = 6291456000,
};
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
BucketName = bucketName,
FilePath = filePath,
PartSize = 6291456000,
Key = keyName,
};
TransferUtility fileTransferUtility = new TransferUtility(client, transferUtilityConfig);
fileTransferUtility.Upload(fileTransferUtilityRequest);
fileTransferUtility.Dispose();
You need a Amazon S3 service URL, an access key id, a secret access key id and the bucket name.
var s3Config = new AmazonS3Config
{
ServiceURL = Constants.AmazonS3ServiceUrl,
RegionEndpoint = Amazon.RegionEndpoint.EUWest1
};
string accessKeyId = Constants.AmazonAccessKeyId;
string secretAccessKey = Constants.AmazonSecretAccessKey;
var config = new AwsS3Config(){AmazonS3BucketName = Constants.AmazonS3BucketName};
var client = new AmazonS3Client(accessKeyId, secretAccessKey, s3Config);
Then, you should be able to make calls to the amazon client:
var request = new GetObjectRequest
{
BucketName = _bucketName,
Key = entity.Path
};
var response = _client.GetObjectAsync(request).Result;
The code above works on an S3 account, not particularly storage.googleapis.com, which is your case. Anyway, I hope this helps and answers your question.

The HTTP request is unauthorized with client authentication scheme 'Anonymous' (Write via C# basic authentication)

I get server error when I trying connect to webService. Do you know why?
Error
{System.Collections.Generic.SynchronizedReadOnlyCollection}
Code
BasicHttpBinding basicbinding = new BasicHttpBinding();
basicbinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
basicbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicbinding.Name = "HTTP_Port";
WSPI.InvoiceCheck_OutClient invoiceCheck_OC = new WSPI.InvoiceCheck_OutClient(basicbinding, new EndpointAddress(new Uri("http://example.example.eu:51200/XISOAPAdapter/MessageServlet?senderParty=&")));
invoiceCheck_OC.ClientCredentials.UserName.UserName = "Login";
invoiceCheck_OC.ClientCredentials.UserName.Password = "Password";
WSPI.InvoiceCheck invoiceCheck = new WSPI.InvoiceCheck();
WSPI.InvoiceCheck_OutRequest invoiceCheck_OR = new WSPI.InvoiceCheck_OutRequest();
WSPI.InvoiceConfirm invoiceCheck_IC = new WSPI.InvoiceConfirm();
invoiceCheck.InvoiceNo = "1000000";
invoiceCheck.IssueDate = "2014-01-01";
invoiceCheck.VatNo = "88090302342";
invoiceCheck.Username = "SuperRafal";
string response = invoiceCheck_OC.InvoiceCheck_Out(invoiceCheck).Response.ToString();
Code working correct there was a problem with link :) Sorry

Categories