Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jersey-dev] [External] : Fwd: Proxy Basic Authentication Tips

Thank you for your response. I tested the ideas, but they did not work.
The first idea was expected to fail, because my problem is that my proxy needs authentication. I try to add my credentials in the same manner, but I keep getting blocked from my proxy.
The second idea was almost there. The new header with my access token was added after the HttpAuthenticationFilter process, but the request was not repeated with this new information. So this time, I don't receive a proxy block, but the API that I'm consuming, returned 401 and that was my final response. Debugging, I see that the filter does not do anything with the request.

https://github.com/eclipse-ee4j/jersey/blob/2.x/core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java#L225

I try to create a BASIC_NON_PREEMPTIVE feature, but this time the first request (to get the token) fails.

Can you help me with other suggestions?
Thanks

Em qua., 30 de ago. de 2023 às 18:27, Jan Supol <jan.supol@xxxxxxxxxx> escreveu:
Ok, the proxy environment is difficult so I cannot test my ideas. I am still a bit confused about who needs the new AUTHORIZATION header. But here the thoughts, hope they can help:

idea 1)
For Second request, do not use the Authentication feature, use it the same way you use it in OkHttp. So you have something like:

ClientBuilder.newClient()
        .property(ClientProperties.PROXY_URI, URI.create("http://yourproxy:yourport"))
        .target("https://external.host").path("/path/to/get/info")
        .request()
        .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken.getValue()).get();
Idea 2)
Use another filter that sets the AUTHORIZATION header after HttpAuthenticationFilter. Given that the repeatRequest of HttpAuthenticationFilter is using the same client, the registered filter should be used as well. So something like:

final AtomicReference<String> reference = new AtomicReference<>();
ClientConfig clientConfig = new ClientConfig();
clientConfig.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(clientConfig);
client.register(httpAuthenticationFeature);
client.register(new ClientRequestFilter() {
    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        String auth = reference.get();
        if (auth != null) {
            requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, auth);
        }
    }
}, /* priority after HttpAuthenticationFilter */ Priorities.AUTHENTICATION + 1);

WebTarget target = client.target("https://external.host");
Response response = target.path("/path/to/generate/access/token").request().get();
AccessToken accessToken = response.readEntity(AccessToken.class);
reference.set(accessToken.getValue());

target.path("/path/to/get/info").request().get();
Would any of these two help?

--Jan

From: Thiago Cardoso Silva <thi.carsil@xxxxxxxxx>
Sent: Wednesday, August 30, 2023 6:50 PM
To: Jan Supol <jan.supol@xxxxxxxxxx>
Cc: jersey-dev@xxxxxxxxxxx <jersey-dev@xxxxxxxxxxx>
Subject: Re: [External] : Fwd: Proxy Basic Authentication Tips
 
I need the filter applied on all requests. But the second request needs an Authorization header.

In the first request, the filter will add an Authorization header with a value containing my corporate user and password in base64. Something like "Basic user_password_base64". This is enough to authenticate with the proxy and continue with the request. This first request give me a token, that I have to pass as an Authorization header as well.

In this case, I add a Authorization header with this value, something like "Authorization Bearer token_from_first_request".

This time, the filter doesn't add the header with my credentials for proxy authentication, so my request is blocked from the proxy. In the second request, when this header is not set, the proxy will send the request, but this time, the API that I'm consuming expects an Authorization header with a token, so I receive an authorization error from the API.

So, my question is, there's a way to accomplish that use case with the HttpAuthenticationFeature or any other mechanism? 

I resolve this with OkHttp using something like this:

Authenticator proxyAuthenticator = new Authenticator() {
  @Override public Request authenticate(Route route, Response response) throws IOException {
       String credential = Credentials.basic(username, password);
       return response.request().newBuilder()
           .header("Proxy-Authorization", credential)
           .build();
  }
};

OkHttpClient client = new OkHttpClient.Builder()
    .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
    .proxyAuthenticator(proxyAuthenticator)
    .build();

This way, every request using this client will make a proxy authentication before proceeds. But we have an internal guideline for Jersey usage, so is very important that we can resolve this using Jersey only.

Thanks in advance.

Em qua., 30 de ago. de 2023 10:55, Jan Supol <jan.supol@xxxxxxxxxx> escreveu:
Hi, sorry for the delay.

To me this looks like you only need the filter to be used when AUTHORIZATION header is not set.
The authentication filter does not do anything when the 
"org.glassfish.jersey.client.authentication.HttpAuthenticationFilter.reused"
property is set to "true". Can you not just set the property in the second request?

-- Jan


From: Thiago Cardoso Silva <thi.carsil@xxxxxxxxx>
Sent: Wednesday, August 16, 2023 6:48 PM
To: Jan Supol <jan.supol@xxxxxxxxxx>; jersey-dev@xxxxxxxxxxx <jersey-dev@xxxxxxxxxxx>
Subject: [External] : Fwd: Proxy Basic Authentication Tips
 
Hi Jan, thanks for your reply.

I think that with a code example I can better explain our needs:

HttpAuthenticationFeature httpAuthenticationFeature =
HttpAuthenticationFeature.basic("myProxyUser", "myProxyPassword");

ClientConfig clientConfig = new ClientConfig();
clientConfig.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(clientConfig);
client.register(httpAuthenticationFeature);

WebTarget target = client.target("https://external.host");
Response response = target.path("/path/to/generate/access/token").request().get();
//This response is ok. The response was a proxy block before HttpAuthenticationFeature
AccessToken accessToken = response.readEntity(AccessToken.class);

//This one give us the proxy block again.
target.path("/path/to/get/info").request()
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken.getValue())
.get();

We are trying to use a CredentialsProvider as well, but without success until now.

Thanks in advance.

Em qua., 16 de ago. de 2023 às 12:47, Jan Supol <jan.supol@xxxxxxxxxx> escreveu:
Hi,
I am not sure I understand the issue.

  • We saw that the HttpAuthenticationFilter adds an Authorization header with the basic authentication, and that's why there's a condition to not execute the authentication process if this header exists on the original request.
Do I understand correctly that you want to repeat the authentication again to another endpoint? If so, can you create another filter with higher priority than HttpAuthenticationFilter, remove the REQUEST_PROPERTY_FILTER_REUSED property, and set the new URI in ClientRequestContext?

Or you want to make a completely new request from a filter with a lower priority with the new token you received and repeat a similar logic from repeatRequest method?

-- Jan



From: jersey-dev <jersey-dev-bounces@xxxxxxxxxxx> on behalf of Thiago Cardoso Silva via jersey-dev <jersey-dev@xxxxxxxxxxx>
Sent: Wednesday, August 16, 2023 1:01 AM
To: jersey-dev@xxxxxxxxxxx <jersey-dev@xxxxxxxxxxx>
Cc: Thiago Cardoso Silva <t.cardoso@xxxxxxxxxxxxxx>
Subject: [External] : [jersey-dev] Proxy Basic Authentication Tips
 
Hi!

I'm facing a problem at work and can't find any alternatives. 
We need to call an external API and for that, we have to pass by the proxy with authentication. For the first request, to get an access token, we are using the feature that adds the HttpAuthenticationFilter.

So, for that, with my user and password, everything is ok. But now, I need to call another endpoint passing the token from the previous request as an Authorization header.

We saw that the HttpAuthenticationFilter adds an Authorization header with the basic authentication, and that's why there's a condition to not execute the authentication process if this header exists on the original request.

We got the working using OkHttp, but I know they use another process for the authentication. There's something we can do to provide something similar?

Thanks in advance.


--

Back to the top