/// <summary>
        /// Gets a security token from the federation server.
        /// </summary>
        /// <returns>
        /// The security token, which is basically a JWT token string.
        /// </returns>
        private SecurityTokenAdapter GetSecurityTokenFromServer()
        {
            logger.Info("Getting security token from the auth server");

            var keyPair = sessionKeySupplier.GetKeyPair();

            if (keyPair == null)
            {
                throw new InvalidOperationException("Keypair is not generated, it is null");
            }

            var publicKey = (RsaKeyParameters)keyPair.Public;

            if (publicKey == null)
            {
                throw new InvalidOperationException("Public key is missing in the key pair");
            }

            string publicKeyDerBase64 = null;

            try
            {
                byte[] publicKeyDer = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey).GetDerEncoded();
                publicKeyDerBase64 = Convert.ToBase64String(publicKeyDer);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Failed to convert public key from RsaKeyParameters type to string type", e);
            }

            var certificateAndKeyPair = leafCertificateSupplier.GetCertificateAndKeyPair();

            if (certificateAndKeyPair == null)
            {
                throw new InvalidOperationException("Certificate and key pair are not present");
            }

            var leafCertificate = certificateAndKeyPair.Certificate;

            if (leafCertificate == null)
            {
                throw new InvalidOperationException("Leaf certificate is not present");
            }

            if (certificateAndKeyPair.PrivateKey == null)
            {
                throw new InvalidOperationException("Leaf certificate's private key is missing");
            }

            HashSet <string> intermediateStrings = null;

            if (intermediateCertificateSuppliers != null &&
                intermediateCertificateSuppliers.Count > 0)
            {
                logger.Debug("Intermediate certificate(s) were supplied");

                intermediateStrings = new HashSet <string>();
                foreach (var supplier in intermediateCertificateSuppliers)
                {
                    var supplierCertificateAndKeyPair = supplier.GetCertificateAndKeyPair();
                    if (supplierCertificateAndKeyPair != null &&
                        supplierCertificateAndKeyPair.Certificate != null)
                    {
                        intermediateStrings.Add(Convert.ToBase64String(supplierCertificateAndKeyPair.Certificate.RawData));
                    }
                }
            }

            // create request body to be sent to the auth service
            var url            = this.federationEndpoint + Constants.AUTH_SERVICE_PATH;
            var requestBody    = new X509FederationRequest(publicKeyDerBase64, Convert.ToBase64String(leafCertificate.RawData), intermediateStrings, purpose);
            var httpRequestMsg = new HttpRequestMessage(HttpMethod.Post, new Uri(url));

            httpRequestMsg.Content = ContentHelper.CreateHttpContent(requestBody);

            var keyId = this.tenancyId + Constants.FED_KEY_PATH + AuthUtils.GetFingerPrint(leafCertificate.Thumbprint);

            if (FederationSigner == null)
            {
                FederationSigner = new FederationRequestSigner((RsaKeyParameters)certificateAndKeyPair.PrivateKey, keyId);
            }
            FederationSigner.SignRequest(httpRequestMsg);
            var requestContent = httpRequestMsg.Content.ReadAsStringAsync().Result;

            logger.Debug($"request content to Auth service is {requestContent}");

            HttpResponseMessage response = null;

            try
            {
                if (Client == null)
                {
                    Client = new HttpClient();
                }
                for (int retry = 0; retry < Constants.RETRIES; retry++)
                {
                    // A new copy of the request message needs to be created because it is disposed each time it is sent, and
                    // resending the same request will result in the following error message:
                    // "The request message was already sent. Cannot send the same request message multiple times."
                    var newRequestMessage = HttpUtils.CloneHttpRequestMessage(httpRequestMsg);
                    response = Client.SendAsync(newRequestMessage).Result;
                    if (response.IsSuccessStatusCode)
                    {
                        break;
                    }
                    Thread.Sleep(Constants.RETRY_MILLIS);
                }
                if (response == null || !response.IsSuccessStatusCode)
                {
                    logger.Debug("Received non successful response while trying to get the AUTH token");
                    ResponseHelper.HandleNonSuccessfulResponse(response);
                }
            }
            finally
            {
                Client.Dispose();
                Client = null;
            }

            var securityTokenContent = response.Content.ReadAsStringAsync().Result;
            var securityToken        = JsonConvert.DeserializeObject <SecurityToken>(securityTokenContent);

            logger.Info($"Security Token received from the Auth Service");
            return(new SecurityTokenAdapter(securityToken.Token));
        }
Example #2
0
 /// <summary>The API requests made by the instance are signed by the private key.</summary>
 /// <returns>Returns the private key.</returns>
 public RsaKeyParameters GetPrivateKey()
 {
     return((RsaKeyParameters)sessionKeySupplier.GetKeyPair().Private);
 }