Is there a way to implement preemptive basic authentication with Apache 
HttpClient 5.2 using a HttpRequestInterceptor similar to how it's done here 
(accepted 
response)<https://stackoverflow.com/questions/2014700/preemptive-basic-authentication-with-apache-httpclient-4>
 for Apache HttpClient 4?



We use Apache HttpClient both directly and as the RestTemplate underlying Http 
client. Preemptive auth used to work with HttpClient 4 using 
HttpRequestInterceptor (see the accepted response for the question I linked 
above), but we can't reuse the same code as the AuthScheme class is now gone.



I tried a few of things but neither worked (see below). Every first request 
gets a 401 from the server, the client retries with basic auth and gets a 
successful response. This is not the behaviour I want though; the first request 
should add the Authorisation header with Basic auth as it used to.
@Component
public class HttpClientPreemptiveAuthInterceptor implements 
HttpRequestInterceptor {

    @Override
    public void process(HttpRequest httpRequest, EntityDetails entityDetails, 
HttpContext httpContext) throws IOException, HttpException {

        // Apparently, we have two options:
        // - Set HttpContext AuthCache with Basic auth for the target.
        // - Copy 
org.apache.hc.client5.http.ContextBuilder#preemptiveBasicAuth()
        // The above method is available for HttpClientContext creation. Not 
sure why it doesn't set AuthCache though,
        // but instead adds an entry to the AuthExchange map of the given http 
context.

        HttpClientContext httpClientContext = (HttpClientContext) httpContext;

        // get the target host from the http context
        RouteInfo routeInfo = httpClientContext.getHttpRoute();
        if (routeInfo != null) {
            HttpHost targetHost = routeInfo.getTargetHost();
            AuthExchange authExchange = 
httpClientContext.getAuthExchange(targetHost);

            if (authExchange.getAuthScheme() == null) {
                CredentialsProvider credentialsProvider = 
httpClientContext.getCredentialsProvider();
                Credentials credentials = 
credentialsProvider.getCredentials(new AuthScope(targetHost.getHostName(), 
targetHost.getPort()), httpClientContext);
                if (credentials == null) {
                    throw new HttpException("No credentials provided for 
preemptive authentication");
                }
                BasicScheme authScheme = new BasicScheme();
                authScheme.initPreemptive(credentials);
                //authExchange.select(authScheme);
                //httpClientContext.setAuthExchange(targetHost, authExchange);
                DefaultSchemePortResolver schemePortResolver = 
DefaultSchemePortResolver.INSTANCE;
                
httpClientContext.resetAuthExchange(RoutingSupport.normalize(targetHost, 
schemePortResolver), authScheme);
            }

        }


        /** Second approach
        // get the target host from the http context
        RouteInfo routeInfo = httpClientContext.getHttpRoute();
        if (routeInfo != null) {
            HttpHost targetHost = routeInfo.getTargetHost();
            // add Basic Auth for the target host (credentials for this host 
will be selected from the CredentialsProvider)
            httpClientContext.resetAuthExchange(targetHost, new BasicScheme());
        }
         **/

        // Third approach
        // Create AuthCache instance
        // final AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local auth cache
        // authCache.put(targetHost, new BasicScheme());
        // httpClientContext.setAuthCache(new BasicAuthCache());
    }

Cheers
Giovanni D’Ascola
The information contained in this message is proprietary and/or confidential. 
If you are not the intended recipient, please: (i) delete the message and all 
copies; (ii) do not disclose, distribute or use the message in any manner; and 
(iii) notify the sender immediately. In addition, please be aware that any 
message addressed to our domain is subject to archiving and review by persons 
other than the intended recipient. FIS is a trading name of the following 
companies: Alphakinetic Limited (No: 06897969) | FIS Derivatives Utility 
Services (UK) Limited (No: 9398140) | FIS Energy Solutions Limited (No: 
1889028) | FIS Global Execution Services Limited (No. 3127109) | FIS Capital 
Markets UK Limited (No: 982833) | FIS Treasury Centre Limited (No. 13543636) | 
Metavante Technologies Limited (No: 2659326) | Virtus Partners Limited (No: 
06602363) | Worldpay (UK) Limited (No: 07316500 / FCA No: 530923) | Worldpay 
Limited (No: 03424752 / FCA No: 504504) | Worldpay AP Limited (No: 05593466 / 
FCA No: 502597) all registered in England & Wales with their registered office: 
C/O F I S Corporate Governance, The Walbrook Building, 25 Walbrook, London, 
EC4N 8AF. The WorldPay entities are authorised by the Financial Conduct 
Authority under the Payment Service Regulations 2017 for the provision of 
payment services. | Worldpay (UK) Limited is authorised and regulated by the 
Financial Conduct Authority for consumer credit activities | FIS Global 
Execution Services Limited is authorised and regulated by the Financial Conduct 
Authority | FIS Banking Solutions UK Limited (No: 3517639) and FIS Payments 
(UK) Limited (No: 4215488) are registered in England & Wales with their 
registered office at 1st Floor Tricorn House, 51-53 Hagley Road, Edgbaston, 
Birmingham, West Midlands, B16 8TU, United Kingdom | FIS Payments (UK) Limited 
is authorised and regulated by the Financial Conduct Authority; some services 
are covered by the Financial Ombudsman Service (in the UK). Worldpay B.V. has 
its registered office in Amsterdam, the Netherlands (Handelsregister KvK No: 
60494344). WPBV holds a licence from and is included in the register kept by De 
Nederlandsche Bank, which registration can be consulted through www.dnb.nl. 
Calls to and from the companies may be recorded for quality purposes. | All of 
the named companies are ultimately owned by Fidelity National Information 
Services, Inc., an NYSE listed trading Company with the ticker symbol FIS.

Reply via email to