515 lines
21 KiB
C#
515 lines
21 KiB
C#
#region Using Statements
|
|
|
|
using System.Net;
|
|
using System.Net.Security;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text.Json;
|
|
|
|
#endregion
|
|
|
|
namespace ClearstreamAPIConnector
|
|
{
|
|
class Program
|
|
{
|
|
// callback used to validate the certificate in an SSL conversation
|
|
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
|
|
{
|
|
var result = cert.Subject.Contains("YourServerName");
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get our refresh token
|
|
/// </summary>
|
|
/// <param name="originalToken"></param>
|
|
/// <returns></returns>
|
|
private static async Task<Token?> GetRefreshTokenAsync(Token originalToken)
|
|
{
|
|
const string username = "stb2_01014165_1000181";
|
|
const string certPw = "clearstream";
|
|
|
|
#region Private Member
|
|
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
|
|
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
|
|
#endregion
|
|
|
|
Token? tok = null;
|
|
|
|
// First create a proxy object
|
|
var proxy = new WebProxy
|
|
{
|
|
Address = new Uri($"http://l7fwout.usinet.it:3128"),
|
|
BypassProxyOnLocal = false,
|
|
UseDefaultCredentials = false,
|
|
Credentials = CredentialCache.DefaultNetworkCredentials
|
|
};
|
|
|
|
|
|
// check certificate chain
|
|
ServicePointManager.ServerCertificateValidationCallback =
|
|
(sender, certificate, chain, sslPolicyErrors) =>
|
|
{
|
|
Console.WriteLine("Ssl Policy Errors:");
|
|
switch (sslPolicyErrors)
|
|
{
|
|
case SslPolicyErrors.None:
|
|
Console.WriteLine("No error in certificate found");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNotAvailable:
|
|
Console.WriteLine("RemoteCertificateNotAvailable");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNameMismatch:
|
|
Console.WriteLine("RemoteCertificateNameMismatch");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateChainErrors:
|
|
Console.WriteLine("RemoteCertificateChainErrors");
|
|
break;
|
|
}
|
|
|
|
// call our validation logic
|
|
//return ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors);
|
|
Console.WriteLine("Overriding cert chain errors. Proceeding...");
|
|
return true;
|
|
};
|
|
|
|
// configure endpoint and certificate
|
|
try
|
|
{
|
|
var remoteAddress = $"{clearstreamApiEndpointUrl}authmanager/oauth2/access_token";
|
|
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
|
|
var certificates = new X509Certificate2Collection();
|
|
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
|
|
|
// values to pass on to service
|
|
var values = new Dictionary<string, string>
|
|
{
|
|
{ "grant_type", "refresh_token" },{"refresh_token",originalToken.refresh_token},
|
|
{ "username", username},
|
|
};
|
|
|
|
// encode it in url form...
|
|
var data = new FormUrlEncodedContent(values);
|
|
|
|
// use modern http client implementation to call endpoint
|
|
using var httpHandler = new HttpClientHandler();
|
|
httpHandler.ClientCertificates.Add(certificates[0]);
|
|
httpHandler.Proxy = proxy;
|
|
|
|
using var client = new HttpClient(httpHandler);
|
|
// handle communiction with API
|
|
var response = await client.PostAsync(remoteAddress, data);
|
|
|
|
// get our response content
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
// get our token
|
|
tok = JsonSerializer.Deserialize<Token>(responseContent);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Exception: {ex.Message}.");
|
|
}
|
|
|
|
return tok;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Elibility Token
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private static async Task<Token> GetElibilityTokenAsync()
|
|
{
|
|
//string scope = "allow ocapi-playground-v1";
|
|
var scopeDi = "allow digital-instruments";
|
|
var username = "stb2_01014165_1000181";
|
|
var password = "Creation1,";
|
|
var certPw = "clearstream";
|
|
|
|
#region Private Member
|
|
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
|
|
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
|
|
#endregion
|
|
|
|
Token? tok = null;
|
|
|
|
// First create a proxy object
|
|
//var proxy = new WebProxy
|
|
//{
|
|
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
|
|
// BypassProxyOnLocal = false,
|
|
// UseDefaultCredentials = false,
|
|
|
|
// Credentials = CredentialCache.DefaultNetworkCredentials
|
|
//};
|
|
|
|
// check certificate chain
|
|
ServicePointManager.ServerCertificateValidationCallback =
|
|
(sender, certificate, chain, sslPolicyErrors) =>
|
|
{
|
|
Console.WriteLine("Ssl Policy Errors:");
|
|
switch (sslPolicyErrors)
|
|
{
|
|
case SslPolicyErrors.None:
|
|
Console.WriteLine("No error in certificate found");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNotAvailable:
|
|
Console.WriteLine("RemoteCertificateNotAvailable");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNameMismatch:
|
|
Console.WriteLine("RemoteCertificateNameMismatch");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateChainErrors:
|
|
Console.WriteLine("RemoteCertificateChainErrors");
|
|
break;
|
|
}
|
|
|
|
Console.WriteLine("Overriding cert chain errors. Proceeding...");
|
|
return true;
|
|
};
|
|
|
|
// configure endpoint and certificate
|
|
try
|
|
{
|
|
var remoteAddress = $"{clearstreamApiEndpointUrl}authmanager/oauth2/access_token";
|
|
var certFile = @".\Cert\P12\xact-api-credentials-3des.p12";
|
|
X509Certificate2Collection certificates = new();
|
|
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
|
|
|
// values to pass on to service
|
|
var values = new Dictionary<string, string>
|
|
{
|
|
{ "grant_type", "password" },
|
|
//{ "scope", scope},
|
|
{"scope", scopeDi },
|
|
{ "username", username},
|
|
{ "password", password},
|
|
};
|
|
|
|
// encode it in url form...
|
|
var data = new FormUrlEncodedContent(values);
|
|
|
|
// use modern http client implementation to call endpoint
|
|
using var httpHandler = new HttpClientHandler();
|
|
|
|
httpHandler.ClientCertificates.Add(certificates[0]);
|
|
//httpHandler.Proxy = proxy;
|
|
|
|
using var client = new HttpClient(httpHandler);
|
|
// handle communiction with API
|
|
var response = await client.PostAsync(remoteAddress, data);
|
|
|
|
// get our response content
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
// get our token
|
|
tok = JsonSerializer.Deserialize<Token>(responseContent);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Exception: {ex.Message}.");
|
|
}
|
|
|
|
return tok;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all associcated templates
|
|
/// </summary>
|
|
/// <param name="accessToken">Bearer token derived from OAuth2.0 request</param>
|
|
/// <returns>JSON with all templates available as a <see cref="string"/></returns>
|
|
static async Task<DiTemplateList> GetAllTemplates(Token accessToken)
|
|
{
|
|
Console.WriteLine("Attempting to get all templates for our account");
|
|
|
|
if (accessToken == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(accessToken));
|
|
}
|
|
|
|
DiTemplateList templates = null;
|
|
var certPw = "clearstream";
|
|
|
|
#region Private Member
|
|
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
|
|
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
|
|
#endregion
|
|
|
|
var remoteAddress = $"{clearstreamApiEndpointUrl}digital-instruments/di/templates";
|
|
|
|
// First create a proxy object
|
|
// var proxy = new WebProxy
|
|
// {
|
|
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
|
|
// BypassProxyOnLocal = false,
|
|
// UseDefaultCredentials = false,
|
|
// Credentials = CredentialCache.DefaultNetworkCredentials
|
|
// };
|
|
|
|
try
|
|
{
|
|
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
|
|
var certificates = new X509Certificate2Collection();
|
|
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
|
|
|
// use modern http client implementation to call endpoint
|
|
using var httpHandler = new HttpClientHandler();
|
|
|
|
httpHandler.ClientCertificates.Add(certificates[0]);
|
|
// httpHandler.Proxy = proxy;
|
|
|
|
using var client = new HttpClient(new LoggingHandler(httpHandler));
|
|
|
|
// handle additional client header
|
|
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.access_token}");
|
|
|
|
// handle communiction with API
|
|
var response = await client.GetAsync(remoteAddress);
|
|
|
|
// get our response content
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
templates = JsonSerializer.Deserialize<DiTemplateList>(responseContent);
|
|
|
|
Console.WriteLine($"Received the following content from {remoteAddress}: '{responseContent}'");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Exception: {ex.Message}.");
|
|
}
|
|
|
|
return templates;
|
|
}
|
|
|
|
/// <summary>
|
|
|
|
/// Call the playground API asynchronously
|
|
/// </summary>
|
|
/// <param name="accessToken"></param>
|
|
/// <returns></returns>
|
|
static async Task<string> CallClearstreamPlaygroundApiAsync(Token accessToken)
|
|
{
|
|
if (accessToken == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(accessToken));
|
|
}
|
|
|
|
var jsonContent = string.Empty;
|
|
var certPw = "clearstream";
|
|
|
|
#region Private Member
|
|
//private static string clearstreamApiEndpointUrl = "https://api.clearstream.com/";
|
|
var clearstreamApiEndpointUrl = "https://api-t2s-test.clearstream.com/";
|
|
#endregion
|
|
|
|
var remoteAddress = $"{clearstreamApiEndpointUrl}/playground/v1/echo?value=Hello%20World";
|
|
|
|
// // First create a proxy object
|
|
// var proxy = new WebProxy
|
|
// {
|
|
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
|
|
// BypassProxyOnLocal = false,
|
|
// UseDefaultCredentials = false,
|
|
// Credentials = CredentialCache.DefaultNetworkCredentials
|
|
// };
|
|
|
|
try
|
|
{
|
|
var certFile = @"./Cert/P12/xact-api-credentials-3des.p12";
|
|
var certificates = new X509Certificate2Collection();
|
|
certificates.Import(certFile, certPw, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
|
|
|
|
// values to pass on to service
|
|
var values = new Dictionary<string, string>();
|
|
|
|
// use modern http client implementation to call endpoint
|
|
using var httpHandler = new HttpClientHandler();
|
|
|
|
httpHandler.ClientCertificates.Add(certificates[0]);
|
|
// httpHandler.Proxy = proxy;
|
|
|
|
using var client = new HttpClient(httpHandler);
|
|
|
|
// handle additional client header
|
|
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.access_token}");
|
|
|
|
// handle communiction with API
|
|
var response = await client.GetAsync(remoteAddress);
|
|
|
|
// get our response content
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
jsonContent = responseContent;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Exception: {ex.Message}.");
|
|
}
|
|
|
|
return jsonContent;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate the whole certificate chain using the cacert certificate
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="certificate"></param>
|
|
/// <param name="chain"></param>
|
|
/// <param name="sslPolicyErrors"></param>
|
|
/// <returns></returns>
|
|
static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
|
{
|
|
Console.WriteLine("Checking server certificate...");
|
|
|
|
if (sslPolicyErrors == SslPolicyErrors.None)
|
|
{
|
|
Console.WriteLine("sslPolicyErrors == SslPolicyErrors.None. Thus returning true to validate certificate from clearstream.");
|
|
return true;
|
|
}
|
|
|
|
Console.WriteLine("Cert issues found. Attempting to load cacert pem from Clearstream.");
|
|
|
|
var privateChain = new X509Chain();
|
|
privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
|
|
|
|
var cert2 = new X509Certificate2(certificate);
|
|
var signerCert2 = new X509Certificate2(@".\Cert\ocapi-stb2_01014165_1000181-cacert.pem");
|
|
|
|
privateChain.ChainPolicy.ExtraStore.Add(signerCert2);
|
|
privateChain.Build(cert2);
|
|
|
|
var isValid = true;
|
|
|
|
Console.WriteLine("Validate Certificate chain manually.");
|
|
foreach (var chainStatus in privateChain.ChainStatus)
|
|
{
|
|
if (chainStatus.Status != X509ChainStatusFlags.NoError)
|
|
{
|
|
Console.WriteLine("chainStatus.Status != X509ChainStatusFlags.NoError");
|
|
|
|
isValid = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Console.WriteLine($"Returning {isValid} as result of cert chain validation.");
|
|
|
|
if (isValid == false)
|
|
{
|
|
Console.WriteLine("Overriding false value for cert result with 'true'");
|
|
isValid = true;
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Main entry point for
|
|
/// </summary>
|
|
/// <param name="args"></param>
|
|
static async Task Main(string[] args)
|
|
{
|
|
try
|
|
{
|
|
// Console.WriteLine("Setting proxy to 'http://l7fwout.usinet.it:3128'");
|
|
|
|
// string resultString = string.Empty;
|
|
var errorOccured = false;
|
|
|
|
// // First create a proxy object
|
|
// var proxy = new WebProxy
|
|
// {
|
|
// Address = new Uri($"http://l7fwout.usinet.it:3128"),
|
|
// BypassProxyOnLocal = false,
|
|
// UseDefaultCredentials = false,
|
|
// Credentials = CredentialCache.DefaultNetworkCredentials
|
|
// };
|
|
|
|
Console.WriteLine("Preparing the request...");
|
|
|
|
// check certificate chain
|
|
ServicePointManager.ServerCertificateValidationCallback =
|
|
(sender, certificate, chain, sslPolicyErrors) =>
|
|
{
|
|
Console.WriteLine("Ssl Policy Errors:");
|
|
switch (sslPolicyErrors)
|
|
{
|
|
case SslPolicyErrors.None:
|
|
Console.WriteLine("No error in certificate found");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNotAvailable:
|
|
Console.WriteLine("RemoteCertificateNotAvailable");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateNameMismatch:
|
|
Console.WriteLine("RemoteCertificateNameMismatch");
|
|
break;
|
|
case SslPolicyErrors.RemoteCertificateChainErrors:
|
|
Console.WriteLine("RemoteCertificateChainErrors");
|
|
break;
|
|
}
|
|
|
|
// call our validation logic
|
|
return ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors);
|
|
};
|
|
|
|
// validate cert by calling a function
|
|
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
|
|
|
|
// first get the access token from clearstream API
|
|
var accessToken = await GetElibilityTokenAsync();
|
|
if (accessToken != null && !string.IsNullOrEmpty(accessToken.access_token))
|
|
{
|
|
Console.WriteLine("Received non null JWT token. Calling Playground Clearstream API");
|
|
Console.WriteLine($"Token: '{accessToken.access_token}'");
|
|
Console.WriteLine($"Refresh Token: {accessToken.refresh_token}");
|
|
Console.WriteLine($"Expires in: {accessToken.expires_in}");
|
|
|
|
// call the playground API
|
|
//resultString = await CallClearstreamPlaygroundApiAsync(accessToken);
|
|
|
|
//Console.WriteLine("For testing purposes, try to regain a new token based on the refresh token.");
|
|
//var refreshToken = await GetRefreshTokenAsync(accessToken);
|
|
//if (refreshToken != null)
|
|
//{
|
|
// Console.WriteLine("Received non null refresh token. Dumping details now:");
|
|
// Console.WriteLine($"Token: '{refreshToken.access_token}'");
|
|
// Console.WriteLine($"Refresh Token: {refreshToken.refresh_token}");
|
|
// Console.WriteLine($"Expires in: {refreshToken.expires_in}");
|
|
//}
|
|
|
|
// next try to call the FIRST real DI method and get the available templates
|
|
var templates = await GetAllTemplates(accessToken);
|
|
if (templates != null && templates.Count > 0)
|
|
{
|
|
Console.WriteLine("Dumping all received templates available for the account used:");
|
|
|
|
var firstTemplate = templates[0];
|
|
|
|
Console.WriteLine($"PartyId: {firstTemplate.partyId}");
|
|
}
|
|
|
|
Console.WriteLine("Successfully called Digital Instruments API.");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Received empty JWT token. Aborting.");
|
|
errorOccured = true;
|
|
}
|
|
|
|
|
|
if (errorOccured)
|
|
{
|
|
Console.WriteLine("Clearstream VNext connectivity test completed with error(s).");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Clearstream VNext connectivity test completed successfully.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Got Exception while running the connetivity check. Message {ex.Message}, Stacktrace: {ex.StackTrace}");
|
|
Console.WriteLine("Clearstream VNext connecivity check FAILED.");
|
|
}
|
|
}
|
|
}
|
|
} |