Explore all HTTP Client open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in HTTP Client

guzzle

Release 7.4.1

vue-resource

Flurl

Flurl.Http 3.2.2

httplug

2.3.0

vue-axios

3.4.1

Popular Libraries in HTTP Client

retrofit

by square doticonjavadoticon

star image 39764 doticonApache-2.0

A type-safe HTTP client for Android and the JVM

guzzle

by guzzle doticonphpdoticon

star image 21585 doticonMIT

Guzzle, an extensible PHP HTTP client

vue-resource

by pagekit doticonjavascriptdoticon

star image 10108 doticonMIT

The HTTP client for Vue.js

Flurl

by tmenier doticoncsharpdoticon

star image 2938 doticonMIT

Fluent URL builder and testable HTTP client for .NET

httplug

by php-http doticonphpdoticon

star image 2310 doticonMIT

HTTPlug, the HTTP client abstraction for PHP

vue-axios

by imcvampire doticonjavascriptdoticon

star image 1906 doticonMIT

A small wrapper for integrating axios to Vuejs

http-client

by symfony doticonphpdoticon

star image 1472 doticonMIT

The HttpClient component provides powerful methods to fetch HTTP resources synchronously or asynchronously.

micropython-lib

by micropython doticonpythondoticon

star image 1373 doticonNOASSERTION

Core Python libraries ported to MicroPython

google-http-java-client

by googleapis doticonjavadoticon

star image 1227 doticonApache-2.0

Google HTTP Client Library for Java

Trending New libraries in HTTP Client

vue-request

by AttoJS doticontypescriptdoticon

star image 516 doticonMIT

⚡️ Vue 3 composition API for data fetching, supports SWR, polling, error retry, cache request, pagination, etc. ⚡️ 一个能轻松帮你管理请求状态(支持SWR,轮询,错误重试,缓存,分页等)的 Vue 3 请求库

thwack

by donavon doticonjavascriptdoticon

star image 272 doticonMIT

A tiny modern data fetching solution

httpcore

by encode doticonpythondoticon

star image 250 doticonBSD-3-Clause

A minimal HTTP client. ⚙️

diseno-para-programadores

by mssroboto doticonjavascriptdoticon

star image 193 doticon

En este repositorio encontrarás el material del curso diseño para programadores.

elasticsearch-java

by elastic doticonjavadoticon

star image 133 doticonApache-2.0

Official Elasticsearch Java Client

NewsRecommendation

by yusanshi doticonpythondoticon

star image 123 doticonMIT

Implementations of some methods in news recommendation.

nft-hooks

by ourzora doticontypescriptdoticon

star image 99 doticonGPL-3.0

NFT Data Fetching Hooks with Zora contract data

http-client

by jiejieTop doticoncdoticon

star image 97 doticonApache-2.0

A high-performance, high-stability, cross-platform HTTP client.

AspNetCore-Practice

by kkbruce doticoncsharpdoticon

star image 83 doticonMIT

ASP.NET Core 專案練習集合,ASP.NET Core Practice Projects

Top Authors in HTTP Client

1

Fictizia

4 Libraries

star icon31

2

googleapis

3 Libraries

star icon1663

3

DanielArturoAlejoAlvarez

3 Libraries

star icon28

4

PacktPublishing

3 Libraries

star icon17

5

phpwebclient

3 Libraries

star icon8

6

divroll

2 Libraries

star icon4

7

KevinDockx

2 Libraries

star icon43

8

Webschool-io

2 Libraries

star icon472

9

Ethiel97

2 Libraries

star icon17

10

tianyucoder

2 Libraries

star icon4

1

4 Libraries

star icon31

2

3 Libraries

star icon1663

4

3 Libraries

star icon17

5

3 Libraries

star icon8

6

2 Libraries

star icon4

7

2 Libraries

star icon43

8

2 Libraries

star icon472

9

2 Libraries

star icon17

10

2 Libraries

star icon4

Trending Kits in HTTP Client

No Trending Kits are available at this moment for HTTP Client

Trending Discussions on HTTP Client

Trouble with On-Behalf-Of flow with standalone Blazor WASM, AAD, .NET Core 6 Web API calling MS Graph

How to change the http client used by pouchDB?

AWS Object Lambda Access Point timing out when writing response when run from within VPC

How can I prevent java.net.http.HttpClient from making an upgrade request?

Nested logic app retries - parent throwing 504

Obtaining a scoped service in a custom delegating handler in Blazor Server

How to send PHP input stream data using curl?

Laravel - Correct way to catch cURL exceception

OkHttp client authentication failing to validate server and send client certificate in the same request

Domain Driven Design: Define boundaries from Domain Model

QUESTION

Trouble with On-Behalf-Of flow with standalone Blazor WASM, AAD, .NET Core 6 Web API calling MS Graph

Asked 2022-Mar-23 at 00:09

I have a standalone Blazor WASM site (client), a separate .NET 6 web API (server) with protected endpoints and I'm trying to call MS Graph from the API.

I've read just about every article I could find on the configuration required to make this work and I'm stuck with the incremental consent failing. I get the following error when trying to access a server API which uses MS Graph:

Error acquiring a token for a downstream web API - MsalUiRequiredException message is: AADSTS65001: The user or administrator has not consented to use the application with ID '[redacted]' named '[redacted]'. Send an interactive authorization request for this user and resource.

Configuration...
  1. Created AAD app for Web API (server), added secret for Graph configuration, set the app URI and created access_as_user scope under "Expose an API" in AAD.

  2. Added the client ID (from the following step) to the knownClientApplications section in the manifest for the server app registration in AAD.

  3. For API Permissions I added Graph scopes User.Read, User.Read.All, and Group.Read.All and provided admin consent in the AAD UI.

  4. Configured appsettings.json in the API to add the Graph API BaseUrl and above scopes from step 2 along with the correct AzureAD domain, TenantId, ClientId, and ClientSecret values for MSAL to function.

  5. Configured MSAL on the server:

1builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2    .AddMicrosoftIdentityWebApi(builder.Configuration)
3    .EnableTokenAcquisitionToCallDownstreamApi()
4        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
5    .AddInMemoryTokenCaches();
6
  1. Created AAD app for Blazor WASM, used SPA auth w/redirect to https://localhost:7014/authentication/login-callback and set the API permissions to api://[redacted]/access_as_user only.

  2. Created custom authorization message handler according to this article.

1builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2    .AddMicrosoftIdentityWebApi(builder.Configuration)
3    .EnableTokenAcquisitionToCallDownstreamApi()
4        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
5    .AddInMemoryTokenCaches();
6public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigation) : base(provider, navigation)
7{
8  ConfigureHandler(
9      authorizedUrls: new[]
10      {
11          "https://localhost:7069"
12      },
13      scopes: new[]
14      {
15          "api://[redacted]/.default"
16      });
17}
18
  1. Configured MSAL on the client:
1builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2    .AddMicrosoftIdentityWebApi(builder.Configuration)
3    .EnableTokenAcquisitionToCallDownstreamApi()
4        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
5    .AddInMemoryTokenCaches();
6public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigation) : base(provider, navigation)
7{
8  ConfigureHandler(
9      authorizedUrls: new[]
10      {
11          "https://localhost:7069"
12      },
13      scopes: new[]
14      {
15          "api://[redacted]/.default"
16      });
17}
18builder.Services.AddMsalAuthentication(options =>
19{
20  builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
21  options.ProviderOptions.DefaultAccessTokenScopes.Add("api://[redacted]/.default");
22  options.ProviderOptions.LoginMode = "redirect";
23}
24
  1. Set up named HTTP client on the Blazor client with custom message handler:
1builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2    .AddMicrosoftIdentityWebApi(builder.Configuration)
3    .EnableTokenAcquisitionToCallDownstreamApi()
4        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
5    .AddInMemoryTokenCaches();
6public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigation) : base(provider, navigation)
7{
8  ConfigureHandler(
9      authorizedUrls: new[]
10      {
11          "https://localhost:7069"
12      },
13      scopes: new[]
14      {
15          "api://[redacted]/.default"
16      });
17}
18builder.Services.AddMsalAuthentication(options =>
19{
20  builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
21  options.ProviderOptions.DefaultAccessTokenScopes.Add("api://[redacted]/.default");
22  options.ProviderOptions.LoginMode = "redirect";
23}
24var baseAddress = builder.Configuration["PublicApiUrl"];
25
26builder.Services.AddHttpClient("PublicApi", client =>
27{
28    client.BaseAddress = new Uri(baseAddress);
29}).AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
30
31builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("PublicApi"));
32builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
33
What works...
  1. I can authenticate as an AAD user to the Blazor client.
  2. I can access protected endpoints (using policy-based authorization) hosted on the server which don't have a dependency on MS Graph.
Questions...
  1. Following this article's guidance about incremental consent, specifically the "Static permissions" section, I would assume granting admin consent for Graph on the server's app registration would suffice?

  2. All of the documentation showing Blazor WASM with a protected API calling a protected API (Graph) assume the Blazor client is also hosted by the API server. Is it even possible to use on-behalf-of flow in my case? If it was hosted I could see the API calling the Blazor navigation subsystem to perform an incremental consent redirect but when they're separated, I can only imagine the static permissions is the way to go.

  3. Is it necessary to set the DefaultAccessTokenScopes in the client?

ANSWER

Answered 2022-Mar-10 at 22:30

The issue here is use of the AddMicrosoftGraph method when the API application is being built.

The GraphServiceClient created by AddMicrosoftGraph will have default access to delegated permissions which are assigned to users as opposed to application permissions which are assigned to applications. This is why the MsalUiRequiredException is being thrown which is usually resolved by prompting the user to login.

You can read more about delegated vs application permissions here.

What you can do instead is use the AddMicrosoftGraphAppOnly method to create a GraphServiceClient that will use credentials specific to your API to retrieve the relevant data needed from the Microsoft Graph API.

1builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2    .AddMicrosoftIdentityWebApi(builder.Configuration)
3    .EnableTokenAcquisitionToCallDownstreamApi()
4        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
5    .AddInMemoryTokenCaches();
6public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigation) : base(provider, navigation)
7{
8  ConfigureHandler(
9      authorizedUrls: new[]
10      {
11          "https://localhost:7069"
12      },
13      scopes: new[]
14      {
15          "api://[redacted]/.default"
16      });
17}
18builder.Services.AddMsalAuthentication(options =>
19{
20  builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
21  options.ProviderOptions.DefaultAccessTokenScopes.Add("api://[redacted]/.default");
22  options.ProviderOptions.LoginMode = "redirect";
23}
24var baseAddress = builder.Configuration["PublicApiUrl"];
25
26builder.Services.AddHttpClient("PublicApi", client =>
27{
28    client.BaseAddress = new Uri(baseAddress);
29}).AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
30
31builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("PublicApi"));
32builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
33builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
34    .AddMicrosoftIdentityWebApi(builder.Configuration)
35    .EnableTokenAcquisitionToCallDownstreamApi()
36    .AddMicrosoftGraphAppOnly(
37        authenticationProvider => new GraphServiceClient(authenticationProvider))
38    .AddInMemoryTokenCaches();
39

So long as you have the relevant settings and secrets provided in the AzureAd section of your appsettings.json file the GraphServiceClient injected into your application should now be able to access the data you need.

You can read more about app configuration with the AzureAd settings in your appsettings.json file here.

Source https://stackoverflow.com/questions/71372824

QUESTION

How to change the http client used by pouchDB?

Asked 2022-Jan-14 at 14:53

I am using PouchDB and CouchDB in an ionic application. While I can successfully sync local and remote databases on Chrome and Android, I get unauthorized error on Safari / iOS when I run the sync command. Below is a simplified version of my database service provider.

1import PouchDB from 'pouchdb';
2import PouchDBAuthentication from 'pouchdb-authentication';
3
4@Injectable()
5export class CouchDbServiceProvider {
6    private db: any;
7    private remote: any;
8    constructor() {
9      PouchDB.plugin(PouchDBAuthentication);
10      this.db = new PouchDB('localdb', {skip_setup: true});
11    }
12    ...
13    login(credentials) {
14      let couchDBurl = 'URL of my couchDB database';
15      this.remote = new PouchDB(couchDBurl); 
16      this.remote.logIn(credentials.username, credentials.password, function (err, response) {
17            if (err) { concole.log('login error') }
18            else {
19                let options = { live: true, retry: true, continuous: true };
20                this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
21            }
22      })
23    }
24    ...
25}
26

In the code above, this.remote.logIn(...) is successful but this.db.sync(...) fails. I have checked the requests via the network tab of developer tools and I believe the issue is that the cookie that's retruned in the response header of this.remote.logIn(...) is not used by the subsequent calls (thus the unauthorized error). The issue is fixed once third-party cookies are enabled on Safari, which is not an option on iOS.

How can I fix this problem?

One potential solution I'm considering is overriding fetch to use native http client (i.e., an instance of HTTP from @ionic-native/http). It seems modifying http clients is a possibility (e.g., according to this conversation) but I'm not sure how to achieve that.

ANSWER

Answered 2022-Jan-11 at 00:41

Changing the HTTP plumbing sounds like a really bad idea - time cost, mainly - unless you just absolutely have to use sessions/cookies...If you don't, read on.

as noted here regarding pouchDB Security, I tried using pouchdb-authentication when it was actively maintained and went another route due to multiple issues (I don't recall specifics, it was 6 years ago).

Do note the last commit to pouchdb-authentication seems to be 3 years ago. Although inactivity is not an negative indicator on the surface - a project may have simply reached a solid conclusion - installing pouchdb-authentication yields this

1import PouchDB from 'pouchdb';
2import PouchDBAuthentication from 'pouchdb-authentication';
3
4@Injectable()
5export class CouchDbServiceProvider {
6    private db: any;
7    private remote: any;
8    constructor() {
9      PouchDB.plugin(PouchDBAuthentication);
10      this.db = new PouchDB('localdb', {skip_setup: true});
11    }
12    ...
13    login(credentials) {
14      let couchDBurl = 'URL of my couchDB database';
15      this.remote = new PouchDB(couchDBurl); 
16      this.remote.logIn(credentials.username, credentials.password, function (err, response) {
17            if (err) { concole.log('login error') }
18            else {
19                let options = { live: true, retry: true, continuous: true };
20                this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
21            }
22      })
23    }
24    ...
25}
26found 6 vulnerabilities (2 moderate, 3 high, 1 critical)
27

That plus the lack of love given to plugin over the last few years makes for a dangerous technical debt to add for a new project.

If possible simply send credentials using the auth option when creating (or opening) a remote database, e.g.

1import PouchDB from 'pouchdb';
2import PouchDBAuthentication from 'pouchdb-authentication';
3
4@Injectable()
5export class CouchDbServiceProvider {
6    private db: any;
7    private remote: any;
8    constructor() {
9      PouchDB.plugin(PouchDBAuthentication);
10      this.db = new PouchDB('localdb', {skip_setup: true});
11    }
12    ...
13    login(credentials) {
14      let couchDBurl = 'URL of my couchDB database';
15      this.remote = new PouchDB(couchDBurl); 
16      this.remote.logIn(credentials.username, credentials.password, function (err, response) {
17            if (err) { concole.log('login error') }
18            else {
19                let options = { live: true, retry: true, continuous: true };
20                this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
21            }
22      })
23    }
24    ...
25}
26found 6 vulnerabilities (2 moderate, 3 high, 1 critical)
27const credentials = { username: 'foo', passwd: 'bar' };
28this.remote = new PouchDB(couchDBurl, { auth: credentials }); 
29

I don't recall why but I wrote code that is in essence what follows below, and have reused it ad nauseum because it just works with the fetch option

1import PouchDB from 'pouchdb';
2import PouchDBAuthentication from 'pouchdb-authentication';
3
4@Injectable()
5export class CouchDbServiceProvider {
6    private db: any;
7    private remote: any;
8    constructor() {
9      PouchDB.plugin(PouchDBAuthentication);
10      this.db = new PouchDB('localdb', {skip_setup: true});
11    }
12    ...
13    login(credentials) {
14      let couchDBurl = 'URL of my couchDB database';
15      this.remote = new PouchDB(couchDBurl); 
16      this.remote.logIn(credentials.username, credentials.password, function (err, response) {
17            if (err) { concole.log('login error') }
18            else {
19                let options = { live: true, retry: true, continuous: true };
20                this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
21            }
22      })
23    }
24    ...
25}
26found 6 vulnerabilities (2 moderate, 3 high, 1 critical)
27const credentials = { username: 'foo', passwd: 'bar' };
28this.remote = new PouchDB(couchDBurl, { auth: credentials }); 
29const user = { name: 'foo', pass: 'bar' };
30const options = { fetch: function (url, opts) {
31    opts.headers.set('Authorization', 'Basic ' + window.btoa(user.name+':'+user.pass));
32    return PouchDB.fetch(url, opts);
33  }
34};
35
36this.remote = new PouchDB(couchDBurl, options); 
37

I believe I chose this approach due to the nature of my authentication workflow discussed in the first link of this answer.

Source https://stackoverflow.com/questions/70658479

QUESTION

AWS Object Lambda Access Point timing out when writing response when run from within VPC

Asked 2022-Jan-13 at 13:39

I've got an AWS Object Lambda Access Point. (These are sort of like a proxy lambda function which can intercept S3 requests and transform them.) It runs fine when not run inside a VPC (so I think IAM is fine). A later iteration will want to access private resources so I want it running inside a VPC.

The flow of one of these lambdas (at least when transforming a GET request) is:

  1. Get invoked
  2. Download the object that was requested using a HTTP client (you get a pre-signed URL to grant access (getObjectContext.inputS3Url in the payload))
  3. Do your transformation
  4. Write the result using s3.Client.WriteGetObjectResponse

It's the last step that isn't working for me.

In my VPC I've added a gateway endpoint for S3 (for S3 either gateway or interface endpoints are supported; gateways are free. This works fine to fetch the object (step 2), I can download the object and work on it. I think that download happens through the gateway endpoint. So far so good.

But after doing the processing it times out when trying to write the response (step 4). In the logs it looks like this:

1POST /WriteGetObjectResponse?x-id=WriteGetObjectResponse HTTP/1.1
2Host: io-cell002.s3-object-lambda.eu-west-2.amazonaws.com
3...
4DEBUG retrying request s3-object-lambda/WriteGetObjectResponse, attempt 2
5...
6time="2022-01-02T22:25:39Z" level=error msg="Error writing to S3: operation error S3: WriteGetObjectResponse, https response error StatusCode: 0, RequestID: , HostID: , canceled, context deadline exceeded"
7

Which smells to me like I can't connect to the endpoint at a network level.

I tried adding an interface endpoint for Lambda (this is the only option returned - see screenshot down below), but that doesn't seem to make any difference. Perhaps this doesn't cover s3-object-lambda.<region>.amazonaws.com? Or maybe it wasn't being used - not sure how to tell that.

A picture showing that there is only an interface endpoint returned for lambda

I also tried adding an interface endpoint for S3, and removing the gateway one referenced above. This caused the Lambda to not be able to even retrieve the input object from S3 in step 2, with an i/o timeout.

(What does also work is adding a NAT gateway to the VPC, but I'd rather avoid the cost of this and AFAICT it shouldn't be necessary.)

Any help getting this working with a VPC / without NAT would be gratefully received!

ANSWER

Answered 2022-Jan-13 at 13:39

The short answer is: You can run your object lambda function in a VPC as long as you allow it to route to s3-object-lambda..amazonaws.com through the internet, e.g. through a NAT gateway. You were on the right track and basically figured it out in your question already.

The S3 gateway interface endpoint is necessary to enable download of the input object.

When writing the result, the request goes to s3-object-lambda, which is technically a different service than S3 (at least on network level). AWS currently doesn't provide an interface endpoint for s3-object-lambda and the S3 gateway endpoint doesn't cover it either (which can be verified by comparing the IP address WriteGetObjectResponse request goes to and the routes created by the gateway endpoint).

So the only way is to route WriteGetObjectResponse requests via opened access to the internet. For future reference, one way to set this up is with a NAT gateway. Quoting AWS docs:

  • The NAT gateway must be in a public subnet with a route table that routes internet traffic to an internet gateway.
  • Your instance must be in a private subnet with a route table that routes internet traffic to the NAT gateway.
  • Check that there are no other route table entries that route all or part of the internet traffic to another device instead of the NAT gateway.

In other words:

  • Provision a public NAT Gateway in a public subnet and allocate it an elastic IP
  • Make sure the public subnet has an internet gateway and the default route (0.0.0.0/0) points to it.
  • Set up a default route (0.0.0.0/0) from the subnet hosting your lambda and point it to the NAT Gateway.

You're right that a NAT Gateway is priced by the hour, unfortunately, and you need one per subnet.

In theory, you could at least limit the egress with a security group to IP addresses of the s3-object-lambda service, but I'm not aware these IP ranges are published anywhere.

Source https://stackoverflow.com/questions/70560503

QUESTION

How can I prevent java.net.http.HttpClient from making an upgrade request?

Asked 2022-Jan-12 at 11:05

Upon making a call from a Java project to a Python rest API, I am met with an error that states "Unsupported upgrade request."

I'm making a simple GET request from Java, to the endpoint written in Python, and at some point Java decides it wants to request to upgrade the connection to a websocket. My issue is, I never reference websockets in my Java project whatsoever, and when I debug and look at the value of headers in the request, it does not show any headers at all, but at some point before it hits the network it decides it wants to do an upgrade request. I haven't sniffed my own traffic to confirm the existence of the header yet; but the problem does not exist when I use OKHTTP instead of java.net.http.HttpClient

This code results in the Unsupported Upgrade Request error returned by the Python API.

1HttpRequest request = HttpRequest.newBuilder()
2    .uri(URI.create(&quot;http://127.0.0.1:8000/&quot;))
3    .method(&quot;GET&quot;, HttpRequest.BodyPublishers.noBody())
4    .build();
5HttpResponse&lt;String&gt; response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
6System.out.println(response.body());
7

This code works just fine

1HttpRequest request = HttpRequest.newBuilder()
2    .uri(URI.create(&quot;http://127.0.0.1:8000/&quot;))
3    .method(&quot;GET&quot;, HttpRequest.BodyPublishers.noBody())
4    .build();
5HttpResponse&lt;String&gt; response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
6System.out.println(response.body());
7OkHttpClient client = new OkHttpClient();
8
9Request request = new Request.Builder()
10  .url(&quot;http://127.0.0.1:8000/&quot;)
11  .get()
12  .build();
13
14Response response = client.newCall(request).execute();
15

Is anyone familiar with disabling the upgrade request in the native HTTP client java provides?

ANSWER

Answered 2022-Jan-12 at 11:05

Requests shouldn't be upgraded to websocket - but the default for the HttpClient is to request an upgrade to HTTP/2.

If you don't want the HttpClient to request an upgrade to HTTP/2 you can set the version in the request to Version.HTTP_1_1, or set the default version in the HttpClient to Version.HTTP_1_1.

See: HttpRequest.Builder::version or HttpClient.Builder::version

Source https://stackoverflow.com/questions/70592810

QUESTION

Nested logic app retries - parent throwing 504

Asked 2021-Nov-29 at 16:47

I have a nested logic app which takes some time for 4 retries in case of a failure. According to the documentation, the default HTTP timeout is 100 seconds. I'm able to increase the HTTP client timeout value in my code which triggers the parent logic app, but in case of a failure in the child logic app, it is retried 4 times and takes much longer. Meanwhile, the parent logic app responds with a 504 (gateway timeout). There are some more actions to take care of after the child logic app returns a response, so I can't make it asynchronous and return 202 to the code trigger. Is there a way to increase the timeout in the nested logic app without making it async?

E.g. - My nested logic app retried 4 times and failed after 4 minutes LogicApp Failure

However, my code already receives a response of 504 after 2 minutes 9 seconds of triggering the parent logic app Response error

The HTTP client which triggers the parent logic app has a timeout of 20 minutes. I verified that this timeout value is working, because without it, we were receiving the timeout reponse in 1 minute 40 seconds (100 seconds), which is default HTTP trigger timeout. I'm under the impression that if the nested logic app also doesn't respond within 100 seconds of being triggered, the parent throws a timeout because it didn't receive a response. Is there a way to work around this?

ANSWER

Answered 2021-Sep-16 at 12:03

It might not be possible without asynchronous patterns or async calls but One of the workarounds can be using HTTP+Webhooks where you can set the timeout value.

enter image description here

You can research this more from HERE.

Source https://stackoverflow.com/questions/69159443

QUESTION

Obtaining a scoped service in a custom delegating handler in Blazor Server

Asked 2021-Nov-23 at 10:00

I'm attempting to set up our Blazor Server application to use a custom delegating handler that will attach a bearer token to all outgoing requests to our APIs. The delegating handler uses a token service that handles the retrieval of the token as well as the process for refreshing it if it's expired. The code looks like this:

1public class HttpAuthorizationHandler : DelegatingHandler
2{
3    private ITokenService _tokenService { get; set; }
4
5    public HttpAuthorizationHandler(ITokenService tokenService)
6    {
7        _tokenService = tokenService;
8    }
9
10    protected async override Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
11    {
12        var token = await _tokenService.TryGetToken();
13
14        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;bearer&quot;, token);
15
16        return await base.SendAsync(request, cancellationToken);
17    }
18}
19

I've registered the token service as a scoped service in Startup.cs, with the understanding that the same instance of the service will stay alive in the DI container for the lifetime of the request. If I'm understanding that correctly, this means that I can assign the token values to the service in my App.razor page thusly and pick them up with any subsequent call to the token service:

1public class HttpAuthorizationHandler : DelegatingHandler
2{
3    private ITokenService _tokenService { get; set; }
4
5    public HttpAuthorizationHandler(ITokenService tokenService)
6    {
7        _tokenService = tokenService;
8    }
9
10    protected async override Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
11    {
12        var token = await _tokenService.TryGetToken();
13
14        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;bearer&quot;, token);
15
16        return await base.SendAsync(request, cancellationToken);
17    }
18}
19@code {
20  [Parameter]
21  public string AccessToken { get; set; }
22  [Parameter]
23  public string RefreshToken { get; set; }
24
25  [Inject] private ITokenService _tokenService { get; set; }
26
27  protected override void OnInitialized()
28  {
29    _tokenService.AccessToken = AccessToken.NullIfEmpty() ?? _tokenService.AccessToken;
30    _tokenService.RefreshToken = RefreshToken.NullIfEmpty() ?? _tokenService.RefreshToken;
31  }
32

This seems to work just fine for everything except the delegating handler - the values turn up just fine in a scoped configuration for any other request made to the token service, but when injecting the token service into the delegating handler the token value always comes up null.

Access token in authorization handler comes up null

Unsurprisingly, if I register the service as a singleton, the values propagate to the delegating handler just fine, but that's obviously not a solution. For some reason the DI scope for the handler appears to be different from that of the rest of the application, and I have no idea why. Any ideas? Appreciate the help in advance.

EDIT

With some help from Simply Ged and Andrew Lock, I was able to get quite a bit closer using the IHttpContextAccessor to grab the instance of the ITokenService associated with the request. I was ecstatic when I first logged in and saw it working, but once my excitement wore down I noticed it would stop working correctly a short time later. It turns out that this method only synchronizes the instances on the initial request - after that time, the DI's awkward pipeline management kicks in and maintains the same service instance for every subsequent request, and they all fall out of alignment again. Here's an example of the debug logs from my testing:

1public class HttpAuthorizationHandler : DelegatingHandler
2{
3    private ITokenService _tokenService { get; set; }
4
5    public HttpAuthorizationHandler(ITokenService tokenService)
6    {
7        _tokenService = tokenService;
8    }
9
10    protected async override Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
11    {
12        var token = await _tokenService.TryGetToken();
13
14        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;bearer&quot;, token);
15
16        return await base.SendAsync(request, cancellationToken);
17    }
18}
19@code {
20  [Parameter]
21  public string AccessToken { get; set; }
22  [Parameter]
23  public string RefreshToken { get; set; }
24
25  [Inject] private ITokenService _tokenService { get; set; }
26
27  protected override void OnInitialized()
28  {
29    _tokenService.AccessToken = AccessToken.NullIfEmpty() ?? _tokenService.AccessToken;
30    _tokenService.RefreshToken = RefreshToken.NullIfEmpty() ?? _tokenService.RefreshToken;
31  }
32App.razor:         e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
33AuthStateProvider: e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Initial request - all IDs match
34AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
35AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
36AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
37AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
38AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Clicking around a bunch
39AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
40AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
41AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
42App.razor:         cab70e54-1907-462d-8918-dbd771fabe76 ┐
43AuthStateProvider: cab70e54-1907-462d-8918-dbd771fabe76 ├ Load a new page - ah, crap...
44AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
45AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
46AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
47App.razor:         3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 │
48AuthStateProvider: 3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 ├ Dang it all to heck
49AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
50AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
51AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
52

Andrew Lock's excellent blog post on this topic goes into some very useful detail on why this kind of thing happens - apparently the dependency injection manages the lifetime of the http request pipelines separately from the lifetimes of the http clients themselves, so you can't rely on the pipeline being a part of the same context as the request. He proposes the use of the IHttpContextAccessor as a solution to this problem, but it does not appear to solve the problem in this particular case. I suspect his blog post refers to an earlier version of ASP.NET Core, the behavior of which is not applicable to Blazor apps. In fact, as Alex pointed out, Microsoft specifically advises against using the IHttpContextAccessor for shared state.

ANSWER

Answered 2021-Nov-03 at 00:57

As per the comment, there is an excellent blog post by Andrew Lock that talks about this.

TL;DR

You'll need to use IHttpContextAccessor to resolve the scoped service and get the instance you want.

Example

All credit for this example should be given to Andrew Lock and his blog post, but for quick reference readers of this question, you need to inject the IHttpContextAccessor into your DelegatingHandler and use that to access the correct scoped service.

1public class HttpAuthorizationHandler : DelegatingHandler
2{
3    private ITokenService _tokenService { get; set; }
4
5    public HttpAuthorizationHandler(ITokenService tokenService)
6    {
7        _tokenService = tokenService;
8    }
9
10    protected async override Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
11    {
12        var token = await _tokenService.TryGetToken();
13
14        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(&quot;bearer&quot;, token);
15
16        return await base.SendAsync(request, cancellationToken);
17    }
18}
19@code {
20  [Parameter]
21  public string AccessToken { get; set; }
22  [Parameter]
23  public string RefreshToken { get; set; }
24
25  [Inject] private ITokenService _tokenService { get; set; }
26
27  protected override void OnInitialized()
28  {
29    _tokenService.AccessToken = AccessToken.NullIfEmpty() ?? _tokenService.AccessToken;
30    _tokenService.RefreshToken = RefreshToken.NullIfEmpty() ?? _tokenService.RefreshToken;
31  }
32App.razor:         e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
33AuthStateProvider: e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Initial request - all IDs match
34AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
35AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
36AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
37AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
38AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ├ Clicking around a bunch
39AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
40AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
41AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
42App.razor:         cab70e54-1907-462d-8918-dbd771fabe76 ┐
43AuthStateProvider: cab70e54-1907-462d-8918-dbd771fabe76 ├ Load a new page - ah, crap...
44AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
45AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┐
46AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
47App.razor:         3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 │
48AuthStateProvider: 3c55ff9c-5511-40a1-9fb8-cd00f9fc11c6 ├ Dang it all to heck
49AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
50AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 │
51AuthHandler:       e12f6c80-5cee-44a0-a8a0-d6b783057339 ┘
52public class ScopedMessageHander: DelegatingHandler
53{
54    private readonly ILogger&lt;ScopedMessageHander&gt; _logger;
55    private readonly IHttpContextAccessor _accessor;
56
57    public ScopedMessageHander(ILogger&lt;ScopedMessageHander&gt; logger, IHttpContextAccessor accessor)
58    {
59        _logger = logger;
60        _accessor = accessor;
61    }
62
63    protected override Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
64    {
65        // The HttpContext will be null if used outside a request context, so check in practice!
66        var httpConext = _accessor.HttpContext;
67
68        // retrieve the service from the Request DI Scope
69        var service = _accessor.HttpContext.RequestServices.GetRequiredService&lt;ScopedService&gt;();
70
71        ...
72    }
73}
74

Source https://stackoverflow.com/questions/69801603

QUESTION

How to send PHP input stream data using curl?

Asked 2021-Nov-18 at 08:42
POST

On my local machine, I want to use cURL as an HTTP client like so:

1curl -X POST -F 'email=derp@example.com' -F 'password=blink182' http://example.com
2

The above curl statement uses the HTTP POST method which can be retrieved in PHP like so:

1curl -X POST -F 'email=derp@example.com' -F 'password=blink182' http://example.com
2echo $_POST['email'];       // derp@example.com
3echo $_POST['password'];    // blink182
4
php://input

However, what I really wanted is the data from the PHP input stream php:://input and not from the POST method $_POST.

The PHP input stream can be retrieved in PHP like so:

1curl -X POST -F 'email=derp@example.com' -F 'password=blink182' http://example.com
2echo $_POST['email'];       // derp@example.com
3echo $_POST['password'];    // blink182
4$input = json_decode( file_get_contents( 'php://input' ) );
5echo $input-&gt;email;     // derp@example.com
6echo $input-&gt;password;  // blink182
7

Which brings me to my question, how to send PHP input stream data using curl?

ANSWER

Answered 2021-Nov-18 at 08:42

From the PHP website:

php://input is a read-only stream that allows you to read raw data from the request body. php://input is not available with enctype="multipart/form-data".

So if you specify the Content-Type as application/json using -H "Content-Type: application/json" you ought to get it in the input stream

complete example:

1curl -X POST -F 'email=derp@example.com' -F 'password=blink182' http://example.com
2echo $_POST['email'];       // derp@example.com
3echo $_POST['password'];    // blink182
4$input = json_decode( file_get_contents( 'php://input' ) );
5echo $input-&gt;email;     // derp@example.com
6echo $input-&gt;password;  // blink182
7curl -X POST https://reqbin.com/echo/post/json
8   -H 'Content-Type: application/json'
9   -d '{&quot;email&quot;:&quot;derp@example.com&quot;,&quot;password&quot;:&quot;blink182&quot;}'
10

Source https://stackoverflow.com/questions/70016619

QUESTION

Laravel - Correct way to catch cURL exceception

Asked 2021-Oct-29 at 13:25

I am building a simple REST API package using cURL and would like to catch an error and then return a view. I am able to throw an error if I dd($e) but if I try and return a view it just continues with the code after the catch function. Shouldn't PHP kill the process and just go to the login view?

1try{    
2    $response = Http::timeout(2)-&gt;asForm()-&gt;post('https://' . $this-&gt;ip_address, [
3        'username' =&gt; $this-&gt;username,
4        'password' =&gt; $this-&gt;password
5    ]);
6
7} catch(\Illuminate\Http\Client\ConnectionException $e) {
8    return view('auth.login');
9}
10

If I get a cURL timeout exception I just want to go back to the login page for now. If I put in a bogus IP address obviously it will timeout after 2 seconds, which is what I am testing.

Using Laravel Http client, how can I catch that error and display the auth login view?

ANSWER

Answered 2021-Oct-23 at 09:47

Could you try this please?

1try{    
2    $response = Http::timeout(2)-&gt;asForm()-&gt;post('https://' . $this-&gt;ip_address, [
3        'username' =&gt; $this-&gt;username,
4        'password' =&gt; $this-&gt;password
5    ]);
6
7} catch(\Illuminate\Http\Client\ConnectionException $e) {
8    return view('auth.login');
9}
10try {
11    $response = Http::timeout(2)-&gt;asForm()-&gt;post('https://' . $this-&gt;ip_address, [
12        'username' =&gt; $this-&gt;username,
13        'password' =&gt; $this-&gt;password
14    ]);
15} catch(\Illuminate\Http\Client\ConnectionException $e) {
16    return view('auth.login')-&gt;with('errorMessage', $e-&gt;getMessage());
17}
18

And you can show the error on the frontend, like below;

1try{    
2    $response = Http::timeout(2)-&gt;asForm()-&gt;post('https://' . $this-&gt;ip_address, [
3        'username' =&gt; $this-&gt;username,
4        'password' =&gt; $this-&gt;password
5    ]);
6
7} catch(\Illuminate\Http\Client\ConnectionException $e) {
8    return view('auth.login');
9}
10try {
11    $response = Http::timeout(2)-&gt;asForm()-&gt;post('https://' . $this-&gt;ip_address, [
12        'username' =&gt; $this-&gt;username,
13        'password' =&gt; $this-&gt;password
14    ]);
15} catch(\Illuminate\Http\Client\ConnectionException $e) {
16    return view('auth.login')-&gt;with('errorMessage', $e-&gt;getMessage());
17}
18@if(!empty($errorMessage))
19  &lt;div class=&quot;alert alert-danger&quot;&gt; {{ $errorMessage }}&lt;/div&gt;
20@endif
21

Source https://stackoverflow.com/questions/69649975

QUESTION

OkHttp client authentication failing to validate server and send client certificate in the same request

Asked 2021-Oct-19 at 08:20
I keep editing this question as I dig further into it.

EDIT I'm able to build my OkHttp client to where it includes both the client cert in the Client.SSLContext.KeyManager, and the trusted certs in the Client.SSLContext.TrustManager

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30

However, my client still isn't sending my client certificate (server cert is validated through the trust store successfully). Getting this in the ssl debug logs

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30No X.509 certificate for client authentication, use empty Certificate message instead
31

Here's what my SSLContext looks like on the HttpClient. enter image description here Seems like that should send the client cert named "cureskeystore" in the request?

keystore.jks is built with the following commands

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30No X.509 certificate for client authentication, use empty Certificate message instead
31openssl pkcs12 -export \
32        -name curesKeyStore \
33        -in clientCert.crt \
34        -inkey privateKey.pem \
35        -certfile clientCert.crt \
36        -out chain.p12 \
37        -passout pass:${STORE_PASSWORD}
38
39keytool -importkeystore \
40        -srckeystore chain.p12 \
41        -srcstoretype pkcs12 \
42        -destkeystore keystore.jks \
43        -deststoretype pkcs12 \
44        -storepass ${STORE_PASSWORD} \
45        -srcstorepass ${STORE_PASSWORD} &gt; /dev/null 2&gt;&amp;1
46

I have also tried creating a store with the client cert + -CAfile with the root and intermediate certs:

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30No X.509 certificate for client authentication, use empty Certificate message instead
31openssl pkcs12 -export \
32        -name curesKeyStore \
33        -in clientCert.crt \
34        -inkey privateKey.pem \
35        -certfile clientCert.crt \
36        -out chain.p12 \
37        -passout pass:${STORE_PASSWORD}
38
39keytool -importkeystore \
40        -srckeystore chain.p12 \
41        -srcstoretype pkcs12 \
42        -destkeystore keystore.jks \
43        -deststoretype pkcs12 \
44        -storepass ${STORE_PASSWORD} \
45        -srcstorepass ${STORE_PASSWORD} &gt; /dev/null 2&gt;&amp;1
46# client cert with CAcerts included
47openssl pkcs12 -export -chain \
48        -in clientCert.crt \
49        -inkey privateKey.pem \
50        -out keystore.p12 \
51        -name p12KeyStore \
52        -CAfile caCerts.crt \
53        -caname root \
54        -passout pass:${STORE_PASSWORD}
55
56keytool -importkeystore \
57        -srcstoretype PKCS12 \
58        -destkeystore keystore.jks \
59        -srckeystore keystore.p12 \
60        -alias p12KeyStore \
61        -storepass ${STORE_PASSWORD} \
62        -srcstorepass ${STORE_PASSWORD}
63

Another possible issue is the CertificateRequest not matching my client certificate.

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30No X.509 certificate for client authentication, use empty Certificate message instead
31openssl pkcs12 -export \
32        -name curesKeyStore \
33        -in clientCert.crt \
34        -inkey privateKey.pem \
35        -certfile clientCert.crt \
36        -out chain.p12 \
37        -passout pass:${STORE_PASSWORD}
38
39keytool -importkeystore \
40        -srckeystore chain.p12 \
41        -srcstoretype pkcs12 \
42        -destkeystore keystore.jks \
43        -deststoretype pkcs12 \
44        -storepass ${STORE_PASSWORD} \
45        -srcstorepass ${STORE_PASSWORD} &gt; /dev/null 2&gt;&amp;1
46# client cert with CAcerts included
47openssl pkcs12 -export -chain \
48        -in clientCert.crt \
49        -inkey privateKey.pem \
50        -out keystore.p12 \
51        -name p12KeyStore \
52        -CAfile caCerts.crt \
53        -caname root \
54        -passout pass:${STORE_PASSWORD}
55
56keytool -importkeystore \
57        -srcstoretype PKCS12 \
58        -destkeystore keystore.jks \
59        -srckeystore keystore.p12 \
60        -alias p12KeyStore \
61        -storepass ${STORE_PASSWORD} \
62        -srcstorepass ${STORE_PASSWORD}
63javax.net.ssl|DEBUG|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:671|Consuming CertificateRequest handshake message (
64&quot;CertificateRequest&quot;: {
65  &quot;certificate types&quot;: [ecdsa_sign, rsa_sign, dss_sign]
66  &quot;supported signature algorithms&quot;: [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
67  &quot;certificate authorities&quot;: [redacted, but does not include Entrust]
68}
69)
70javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
71javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp256r1_sha256
72javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
73javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp384r1_sha384
74javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
75javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp521r1_sha512
76javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
77javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha256
78javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
79javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha384
80javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
81javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha512
82javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
83javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha256
84javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
85javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha384
86javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
87javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha512
88javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
89javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha256
90javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
91javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha384
92javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
93javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha512
94javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
95javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha256
96javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
97javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha224
98javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
99javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_sha224
100javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
101javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha224
102javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
103javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha1
104javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
105javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha1
106javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
107javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha1
108javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:774|No available authentication scheme
109

My certificate's signing algorithm is SHA256withRSA. Is that not the same as rsa_pkcs1_sha256? Also, my client certificate is signed by Entrust, which is not listed in the certificate authorities for the server's CertificateRequest.

EDIT: I made some requests to a different HTTPS server that does not include certificate authorities in its CertificateRequest to the client. I verified that SSL can find the expected client certificate and sends it back to the server as expected. So it seems like this is an issue with the server request not including my CA in their list of accepted certificate authorities. Reaching out to the server to request an update.

ANSWER

Answered 2021-Oct-19 at 08:20

Okay; it has developed your problem is that when the server requests your client-cert/auth, it specifies a CA list that doesn't include the CA(s?) used by your cert-and-chain, even though when presented with your cert-and-chain the server accepts it. After commenting about writing a wrapper KeyManager, I realized it would be easy enough to test, and the following example works for me to send a client cert different from what the server asked for. I used SSLSocket directly for simplicity, but anything (like OkHttp) using the same SSLContext or SSLSocketFactory should work. Tested in 8u301 (but I can check some others if you want) against OpenSSL commandline, which lets me request client cert for CA X but when I submit a cert from CA Y it only logs the verification error without aborting the connection.

1// Create keyManagerFactory with keystore.jks
2KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
3clientStore.load(new FileInputStream(new File(&quot;keystore.jks&quot;)), storePassword.toCharArray());
4
5KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
6keyManagerFactory.init(clientStore, storePassword.toCharArray());
7KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
8        
9// Create trustManagerFactory with default cacerts truststore
10TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
11            TrustManagerFactory.getDefaultAlgorithm());
12trustManagerFactory.init((KeyStore) null);
13trustManagers = trustManagerFactory.getTrustManagers();
14if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
15            throw new IllegalStateException(&quot;Unexpected default trust managers:&quot;
16                                                + Arrays.toString(trustManagers));
17        }
18trustManager = trustManagers[0];
19
20// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
21sslContext = SSLContext.getInstance(&quot;TLS&quot;);
22sslContext.init(keyManagers, trustManagers, null);
23sslSocketFactory = sslContext.getSocketFactory();
24defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
25
26okClient = new OkHttpClient
27                 .Builder()
28                 .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
29                 .build();
30No X.509 certificate for client authentication, use empty Certificate message instead
31openssl pkcs12 -export \
32        -name curesKeyStore \
33        -in clientCert.crt \
34        -inkey privateKey.pem \
35        -certfile clientCert.crt \
36        -out chain.p12 \
37        -passout pass:${STORE_PASSWORD}
38
39keytool -importkeystore \
40        -srckeystore chain.p12 \
41        -srcstoretype pkcs12 \
42        -destkeystore keystore.jks \
43        -deststoretype pkcs12 \
44        -storepass ${STORE_PASSWORD} \
45        -srcstorepass ${STORE_PASSWORD} &gt; /dev/null 2&gt;&amp;1
46# client cert with CAcerts included
47openssl pkcs12 -export -chain \
48        -in clientCert.crt \
49        -inkey privateKey.pem \
50        -out keystore.p12 \
51        -name p12KeyStore \
52        -CAfile caCerts.crt \
53        -caname root \
54        -passout pass:${STORE_PASSWORD}
55
56keytool -importkeystore \
57        -srcstoretype PKCS12 \
58        -destkeystore keystore.jks \
59        -srckeystore keystore.p12 \
60        -alias p12KeyStore \
61        -storepass ${STORE_PASSWORD} \
62        -srcstorepass ${STORE_PASSWORD}
63javax.net.ssl|DEBUG|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:671|Consuming CertificateRequest handshake message (
64&quot;CertificateRequest&quot;: {
65  &quot;certificate types&quot;: [ecdsa_sign, rsa_sign, dss_sign]
66  &quot;supported signature algorithms&quot;: [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
67  &quot;certificate authorities&quot;: [redacted, but does not include Entrust]
68}
69)
70javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
71javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp256r1_sha256
72javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
73javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp384r1_sha384
74javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
75javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp521r1_sha512
76javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
77javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha256
78javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
79javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha384
80javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
81javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha512
82javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
83javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha256
84javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
85javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha384
86javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
87javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha512
88javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
89javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha256
90javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
91javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha384
92javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
93javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha512
94javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
95javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha256
96javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
97javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha224
98javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
99javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_sha224
100javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
101javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha224
102javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
103javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha1
104javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
105javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha1
106javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
107javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha1
108javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:774|No available authentication scheme
109public class SO69577136KeyManagerIgnoreCAs  {
110    public static void main (String[] args) throws Exception {
111        // keystore.p12 pw truststore.p12 pw host port [Y: wrap KM to ignore issuers]
112        KeyStore st = KeyStore.getInstance(&quot;PKCS12&quot;);
113        try( InputStream is = new FileInputStream(args[0]) ){ st.load(is,args[1].toCharArray()); }
114        KeyManagerFactory kf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
115        kf.init(st,  args[1].toCharArray());
116        KeyManager[] km = kf.getKeyManagers();
117        try( InputStream is = new FileInputStream(args[2]) ){ st.load(is,args[3].toCharArray()); }
118        TrustManagerFactory tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
119        tf.init(st);
120        TrustManager[] tm = tf.getTrustManagers();
121        
122        if( args.length&gt;6 &amp;&amp; args[6].startsWith(&quot;Y&quot;) ){
123            X509ExtendedKeyManager orig = (X509ExtendedKeyManager)km[0]; // exception if wrong type
124            km[0] = new X509ExtendedKeyManager(){
125
126                @Override
127                public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
128                    return orig.chooseClientAlias(keyType, null, socket);
129                }
130
131                @Override
132                public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
133                    // not implemented
134                    return null;
135                }
136
137                @Override
138                public X509Certificate[] getCertificateChain(String alias) {
139                    return orig.getCertificateChain(alias);
140                }
141
142                @Override
143                public String[] getClientAliases(String keyType, Principal[] issuers) {
144                    // shouldn't actually be used AFAICT but just in case
145                    return orig.getClientAliases(keyType, issuers);
146                }
147
148                @Override
149                public PrivateKey getPrivateKey(String alias) {
150                    return orig.getPrivateKey(alias);
151                }
152
153                @Override
154                public String[] getServerAliases(String keyType, Principal[] issuers) {
155                    // not implemented
156                    return null;
157                }
158
159                public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
160                    return orig.chooseEngineClientAlias(keyType, null, engine);
161                    // could just forward to chooseClientAlias(socket=null), that's what underlying does
162                }
163
164                public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
165                    // not implemented
166                    return null;
167                }
168            };
169        }
170        SSLContext ctx = SSLContext.getInstance(&quot;TLS&quot;);
171        ctx.init(km, tm, null /* default */);
172        SSLSocketFactory sf = ctx.getSocketFactory();
173        SSLSocket ss = (SSLSocket) sf.createSocket(args[4], Integer.parseInt(args[5]));
174        ss.startHandshake();
175        System.out.println (&quot;successful&quot;);
176    }
177}
178

Source https://stackoverflow.com/questions/69577136

QUESTION

Domain Driven Design: Define boundaries from Domain Model

Asked 2021-Oct-06 at 07:49

I am working on a project and I am trying to utilize the concepts of Domain Driven Design.

I have the following domain model: (it is simplified for this question)

enter image description here

Let me explain the system first.

This system is for monitoring data coming from gateways. In this case there are two gateways, but there might be more in reality. Each gateway has its own implementation, so its own entities.

An example of the system is as follows:

A company has a project to monitor ship data.

So they have two gateways. A gateway with type Field-Device-Gateway and a gateway with type HTTP-Client-Gateway.

The first gateway (field-device-gateway) can have multiple field devices. A field device is a small device onboard on a ship. This device receives all data coming from devices on board of the ship. This is through a source (like an address) that has to be setup in the system.

The second gateway (http-client-gateway) can have multiple HTTP clients. Each client may have multiple routes.

So, a gateway also has variables. A variable is a configuration for getting a specific set of data. So, on the field-device-gateway might be a variable specifying to get integer data from a specific device, from a specific field device source, from a specific field device.

The system will make a request to the field device with the new variables. The field device then knows what data to send. It will be received by the system and stored in the database.


So, what am I asking?

Currently, everything is coupled. I need to define boundaries and then aggregates, but I just don't know where to start.

If I would not create boundaries, this will just become an enormous coupled mess and makes it hard to make aggregates.

So, what would the boundaries be? And what about the aggregates, are there even aggregates? Is everything its own aggregate?

And if everything is its own aggregate, how do I enforce some business logic like: A variable can only exist if there is a gateway, project and company.

ANSWER

Answered 2021-Oct-06 at 07:49

Before thinking about boundaries, you have to go back to domains and subdomains.

The problem space is your domains (and subdomains) and your solution space is your Bounded Contexts.

The first important issue in the application of the DDD in a project is to identify your sub-domains and in particular to divide them into the 3 following "families":

  • Core Domain
  • Supporting Subdomain
  • Generic Subdomain

This cutting is driven by this sub-domain families and by the domain expert.

A Bounded Context is a language boundary where context is king. We only know the meaning of a concept thanks to its context (which is also a cultural context).

How to avoid making mistakes in the division of Bounded Contexts?

  • When there are technical or architectural considerations
  • When you try to split a Bounded Context to distribute tasks to free developers
  • If you have two objects that don't have the same definitions, then they must be in two different Bounded Contexts

If you think to all this, you may easily separate your objects (your language) into these Bounded Contexts.

For your Aggregate's problem :

  • Try to decide for each class if it is an Entity or a Value Object (or Domain Service but try to avoid).
  • Your Aggregates are "some" of your main Entities which can drive other Entities

Source https://stackoverflow.com/questions/69450327

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in HTTP Client

Tutorials and Learning Resources are not available at this moment for HTTP Client

Share this Page

share link

Get latest updates on HTTP Client