docusign / docusign-esign-csharp-client

The Official Docusign C# Client Library used to interact with the eSignature REST API. Send, sign, and approve documents using this client.
https://developers.docusign.com/docs/esign-rest-api/sdks/csharp/
MIT License
130 stars 159 forks source link

When using Docker: Error while requesting server, received a non successful HTTP code with response Body: #444

Closed mthomas-github closed 5 months ago

mthomas-github commented 5 months ago

Hello I following steps to JWT Authenction, I have done this already before with another app same code but I'm getting the following with actually no error so don't what happening, check logs on dev site but nothing.

Error while requesting server, received a non successful HTTP code with response Body:

There is no error returned, I have tired switch out private keys and everything still a no go. image image image

mthomas-github commented 5 months ago

The application is running with a Docker Container. And I'm using Clean Architecture Approach,

so the code live in my Infruscture Project, and it being called by a Background Service.

mthomas-github commented 5 months ago

Sorry did not mean to close

mike-mej commented 5 months ago

Hello,

In order to help on this, Could you please share the URL and method used for this rest-api call?

If you have a traceToken will be great as well.

Thanks in advance,

mthomas-github commented 5 months ago

Hello,

In order to help on this, Could you please share the URL and method used for this rest-api call?

If you have a traceToken will be great as well.

Thanks in advance,

Hi This is failing when I'm trying to get a Auth token, cannot even get pass this to actually make any api call.

Integration key: 73e0cf46-6c27-4ca1-b66f-8d11cxxxxxx

ImpersonatedID: 78dabb05-a9a9-456c-9f27-128b430xxxxx

Auth base url: account-d.docusign.com

Private key

image

mthomas-github commented 5 months ago

I download 6.8.0 release code, attach the project to mine and I have notice that the assertion token is invalid

image

mike-mej commented 5 months ago

For the iss value is the integration Key and the aud value is the UserID. You can try using a new RSA keys for testing purposes as well. Please let me know

mthomas-github commented 5 months ago

I validate with a new key same issue one thing I notice vs the assertion key being generated vs a valid one is the first part of a token is not being generated if you notice that the from second image the red section is not being generated.

image

Valid Token image

mike-mej commented 5 months ago

Please allow me to check with my team.

mthomas-github commented 5 months ago

Meantime I going to switch around my code, to rule out any issues, just gonna call the code directly instead of through background service to see if makes any difference, because it makes no sense.

I spun up a Console App and supplied all the same information and I can get an auth token, so I suspect it might be related to my code in a project.

The only difference is One is a Console App and where I'm calling DocuSign is from Class Library

mthomas-github commented 5 months ago

I rechecked to make sure that the JWTToken was correct, it was I was looking at the signature instead of the actual token, I tested that assertion token with Postman and I was able to get a token back,

So where it seems it failing when it sent the HTTPRequeest Async is when I get an internal server error

` public async Task SendRequestAsync(DocuSignRequest request, CancellationToken cancellationToken) { try { var response = await this.SendHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);

       IDictionary<string, string> combinedHeaders = new Dictionary<string, string>();
       response.Headers.ToList().ForEach((kvp) =>
       {
           if (!combinedHeaders.ContainsKey(kvp.Key))
           {
               combinedHeaders.Add(kvp.Key, kvp.Value.FirstOrDefault());
           }
       });
       response.Content.Headers.ToList().ForEach((kvp) => {
           if (!combinedHeaders.ContainsKey(kvp.Key))
           {
               combinedHeaders.Add(kvp.Key, kvp.Value.FirstOrDefault());
           }
       });

       return new DocuSignResponse(
           response.StatusCode,
           combinedHeaders,
           await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false),
           response.Content.Headers?.ContentType?.MediaType);
   }
   catch
   {
       return new DocuSignResponse(System.Net.HttpStatusCode.InternalServerError, null, null, string.Empty);
   }

}`

mthomas-github commented 5 months ago

Also here is how I'm calling the code

image

` public static OAuthToken AuthenticateWithJwt(string clientId, string impersonatedUserId, string authServer, byte[] privateKeyBytes) { var docuSignClient = new DocuSignClient(); var scopes = new List { "signature", "impersonation", };

  return docuSignClient.RequestJWTUserToken(
      clientId,
      impersonatedUserId,
      authServer,
      privateKeyBytes,
      1,
      scopes);

}`

mthomas-github commented 5 months ago

Seem to be an issue when running inside a docker container, I just tried my other project which is non docker container and it worked just fine.

Have you seen this issue before?

mike-mej commented 5 months ago

Thanks a lot for your update, please let me check if this is a known behavior or not.

I will be updating you as well.

garg-mudit commented 5 months ago

Hi @mthomas-github, Are you using the same Integrator Key for the application which is not containerized ? I will be trying to reproduce the issue in Docker but I am assuming this is a consent issue.

Please check if consent is already provided to the IK being used in application running on Docker.

Thank You.

mthomas-github commented 5 months ago

Hi,

Are you using the same Integrator Key for the application which is not containerized ?

I will be trying to reproduce the issue in Docker but I am assuming this is a consent issue.

Please check if consent is already provided to the IK being used in application running on Docker.

Thank You.

Yes same keys no change

garg-mudit commented 5 months ago

Hi @mthomas-github, I tried out a basic setup in Docker for C# eSign Nuget and I was able to get the token using RequestJWTUserToken method.

Here is my Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /App

# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]

and here is my program.cs :

using DocuSign.eSign.Client;
using DocuSign.eSign.Client.Auth;

using DotNet.Docker;

var testConfig = new TestConfig();
testConfig.ApiClient = new DocuSignClient(new Configuration(testConfig.Host) { Timeout = (int)TimeSpan.FromMinutes(50).TotalMilliseconds });

Console.WriteLine(testConfig?.PrivateKey);

byte[] privateKeyStream = testConfig.PrivateKey;

var scopes = new List<string> { OAuth.Scope_SIGNATURE, OAuth.Scope_IMPERSONATION };

OAuth.OAuthToken tokenInfo = testConfig.ApiClient.RequestJWTUserToken(
    testConfig.IntegratorKey,
    testConfig.UserId,
    testConfig.OAuthBasePath,
    privateKeyStream,
    testConfig.ExpiresInHours,
    scopes);

Console.WriteLine(tokenInfo.access_token);

using (MemoryStream ms = new MemoryStream(privateKeyStream))
{
    OAuth.OAuthToken tokenInfoFromStream = testConfig.ApiClient.RequestJWTUserToken(
        testConfig.IntegratorKey,
        testConfig.UserId,
        testConfig.OAuthBasePath,
        ms,
        testConfig.ExpiresInHours,
        scopes);

    Console.WriteLine(tokenInfoFromStream.access_token);
}

OAuth.UserInfo userInfo = testConfig.ApiClient.GetUserInfo(tokenInfo.access_token);

Console.WriteLine(userInfo?.Accounts != null);

Note: The TestConfig present here is same as the class present here

Also I used version 7.0.0-rc2 of DocuSign.eSign.dll.

Please let me know the following:

Thank You.

garg-mudit commented 5 months ago

Btw, did you try to run the ConsoleApp as a Docker Image ? If not, can you please try do that ? It should rule out any network configuration on your Docker instance.

Thank You.

mthomas-github commented 5 months ago

Hi @garg-mudit

  • Which version of the package are you trying out ? 6.8.0
  • Which .Net version are you using ? .net Core 8.0
  • Which method are you using to authenticate ? RequestJWTUserToken
  • Do you have some specific network setting applied to the Docker ? Nope
  • Please recheck if your config (including userid, IK and privateKey) is correct in Docker image. I have verified this, I running it in debug mode

Docker File:


FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["src/ThirdPartyFreight.Api/ThirdPartyFreight.Api.csproj", "src/ThirdPartyFreight.Api/"]
RUN dotnet restore "./src/ThirdPartyFreight.Api/ThirdPartyFreight.Api.csproj"
COPY . .
WORKDIR "/src/src/ThirdPartyFreight.Api"
RUN dotnet build "./ThirdPartyFreight.Api.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./ThirdPartyFreight.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ThirdPartyFreight.Api.dll"]

Docker-Compose

version: '3.4'

services:
  thirdpartyfreight.api:
    image: ${DOCKER_REGISTRY-}thirdpartyfreightapi
    container_name: ThirdPartyFreight.Api
    build:
      context: .
      dockerfile: src/ThirdPartyFreight.Api/Dockerfile
    ports:
        - 28080:8080
        - 28081:8081
  csdtpfblazorwebapp-db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: CSDTPFBlazorWebApp.Db
    environment:
      SA_PASSWORD: "**********"
      ACCEPT_EULA: "Y"
    ports:
        - 1433:1433
    volumes:
        -  ./.containers/database:/var/opt/mssql/data
  csdtpfblazorwebapp-idp:
    image: quay.io/keycloak/keycloak:latest
    container_name: CSDTPFBlazorWebApp.Identity
    environment:
        - KEYCLOAK_ADMIN=admin
        - KEYCLOAK_ADMIN_PASSWORD=admin
    command:
        - start-dev
    ports:
        - 18080:8080
  csdtpfblazorwebapp-seq:
    image: datalust/seq:latest
    container_name: CSDTPFBlazorWebApp.Seq
    environment:
        - ACCEPT_EULA=Y
    ports:
        - 5341:5341
        - 8081:80
  csdtpfblazorwebapp-redis:
    image: redis:latest
    container_name: CSDTPFBlazorWebApp.Redis
    ports:
        - 6379:6379
mthomas-github commented 5 months ago

Btw, did you try to run the ConsoleApp as a Docker Image ? If not, can you please try do that ? It should rule out any network configuration on your Docker instance.

Thank You.

I didn't run console app in Docker.

mthomas-github commented 5 months ago

So I just tested console app, same issue no difference.

here is my docker network just running in bridge mode image

garg-mudit commented 5 months ago

Hi @mthomas-github, Can you please also try doing a simple API call (from within the Docker APP) wherein you are creating your own HTTP Client and just hitting the DocuSign auth endpoint ? I want to better understand if SDK has any hand in this issue or not. Thank You.

garg-mudit commented 5 months ago

Also, Can you please try to use the Test project within this repo within Docker to make your API calls ? As you initially mentioned that you are only getting Error while requesting server, received a non successful HTTP code with response Body: with no other content within this message thus running the test code (which relies on DLL) in debug mode might be helpful as it will show you actual error as its thrown. within DocuSignClient file.

As I am unable to reproduce the issue, thus I am trying to come up with various ways by which we can get some lead on actual issue on your end. Thanks for the patience.

mthomas-github commented 5 months ago

Hi @mthomas-github, Can you please also try doing a simple API call (from within the Docker APP) wherein you are creating your own HTTP Client and just hitting the DocuSign auth endpoint ? I want to better understand if SDK has any hand in this issue or not. Thank You.

So I tried and within docker container, I get SSL Error, outside of the container it returns.

mthomas-github commented 5 months ago

Also, Can you please try to use the Test project within this repo within Docker to make your API calls ? As you initially mentioned that you are only getting Error while requesting server, received a non successful HTTP code with response Body: with no other content within this message thus running the test code (which relies on DLL) in debug mode might be helpful as it will show you actual error as its thrown. within DocuSignClient file.

As I am unable to reproduce the issue, thus I am trying to come up with various ways by which we can get some lead on actual issue on your end. Thanks for the patience.

see below all that comes from the exception it doesn't give me any kind of error not at all.

Document   | Name | Value | Type -- | -- | -- | -- ◢ | $exception | {DocuSign.eSign.Client.ApiException: Error while requesting server, received a non successful HTTP code with response Body: at DocuSign.eSign.Client.DocuSignClient.RequestJWTUserToken(String clientId, String userId, String oauthBasePath, Byte[] privateKeyBytes, Int32 expiresInHours, List`1 scopes) at Program.
$(String[] args) in C:\Users\mthomas\source\WorkRepos\ConsoleApp1\ConsoleApp1\Program.cs:line 15} | DocuSign.eSign.Client.ApiException
mthomas-github commented 5 months ago

Also, Can you please try to use the Test project within this repo within Docker to make your API calls ? As you initially mentioned that you are only getting Error while requesting server, received a non successful HTTP code with response Body: with no other content within this message thus running the test code (which relies on DLL) in debug mode might be helpful as it will show you actual error as its thrown. within DocuSignClient file.

As I am unable to reproduce the issue, thus I am trying to come up with various ways by which we can get some lead on actual issue on your end. Thanks for the patience.

@garg-mudit I tried this the other day, I cloned the repo, and attached it to my project directly, I was able to step through the code, and when it got to sending a request is when it fails with generic message.

Are you saying you don't have any issues when you try with docker? Your post earlier today reads I was unable to get Auth Token.

Here function in the code where fails

public async Task SendRequestAsync(DocuSignRequest request, CancellationToken cancellationToken)
{
try
{
var response = await this.SendHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);

       IDictionary<string, string> combinedHeaders = new Dictionary<string, string>();
       response.Headers.ToList().ForEach((kvp) =>
       {
           if (!combinedHeaders.ContainsKey(kvp.Key))
           {
               combinedHeaders.Add(kvp.Key, kvp.Value.FirstOrDefault());
           }
       });
       response.Content.Headers.ToList().ForEach((kvp) => {
           if (!combinedHeaders.ContainsKey(kvp.Key))
           {
               combinedHeaders.Add(kvp.Key, kvp.Value.FirstOrDefault());
           }
       });

       return new DocuSignResponse(
           response.StatusCode,
           combinedHeaders,
           await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false),
           response.Content.Headers?.ContentType?.MediaType);
   }
   catch
   {
       return new DocuSignResponse(System.Net.HttpStatusCode.InternalServerError, null, null, string.Empty);
   }
}
mthomas-github commented 5 months ago

@garg-mudit & @mike-mej

Okay, I found the actual problem, I was expecting the error was going to be this, but I need to spend more time fixing this issue in my container.......

Actually, Error: "The SSL connection could not be established; see inner exception."

If possible, maybe we can actually return this error in the DLL, so we don't go down a rabbit hole? It's a legit error that can happen.

Since this is a issue with my container I think we can just close it out now.

mthomas-github commented 5 months ago

@garg-mudit Should this work even if I serving my Docker Container within HTTPS Already? I'm passing it a cert to Container as well.

garg-mudit commented 5 months ago

Are you saying you don't have any issues when you try with docker? Your post earlier today reads I was unable to get Auth Token.

Updated my earlier comment. I was able to successfully call the token endpoints.

If possible, maybe we can actually return this error in the DLL, so we don't go down a rabbit hole? It's a legit error that can happen.

We are already aware of this issue and will fix it soon.

mthomas-github commented 5 months ago

@garg-mudit I retested on a new Windows machine with docker, and it worked fine,

After digging around with OpenSLL I found it had something to do with my company policy, so I have to work on getting the correct certs from them I think it might help after that.