0

I'm using KerberosTemplate to make a POST request to a kerberos authenticated rest API.

I can successfully run an insecure request on the command line but when I try to do a secure call with HTTP client It returns a 401 unauthorized error.

I tried to turn of certificate checking as we dont use it and I also tries the username without the domain but that has no affect either.

I also tried to kerb4j rest template too but I get the same issue. From the code you can also see that Im checking the keytab file exists as well.

Appreciate some help, thanks.

import ErrorHandlers.KerberosRestTemplateResponseErrorHandler;
import POJOs.PostBody;
import POJOs.PostResponse;
import com.fasterxml.jackson.databind.SerializationFeature;
//import com.kerb4j.client.spring.KerberosRestTemplate;
import org.springframework.security.kerberos.client.KerberosRestTemplate;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

public class KerbTemplate {
    public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        PostBody postRequestBody = new PostBody();
        postRequestBody.setAggregation("data");
        postRequestBody.setEndDate("2119-03-30");
        postRequestBody.setStartDate("1900-03-30");
        postRequestBody.setMetadata(new String[] {"PARTIAL"});
        postRequestBody.setSymbols(new String[] {"requestdata"});
        postRequestBody.setModifiedDate("2019-07-20");
        postRequestBody.setFirstWeekday("0");

        TrustStrategy acceptingTrustStrategy = ((X509Certificate[] chain, String authType) -> true);
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);

        String base = System.getProperty("user.dir");
        String keytab = base+ File.separator+"src"+File.separator+"main"+File.separator+"resources"+File.separator+"username.keytab";
        System.out.println(keytab);
        File f = new File(keytab);
        if(f.exists() && !f.isDirectory()) {
            System.out.println("File exists");
        }

        KerberosRestTemplate kerberosRestTemplate = new KerberosRestTemplate( keytab,"'username@domain",requestFactory.getHttpClient());
        kerberosRestTemplate.setErrorHandler(new KerberosRestTemplateResponseErrorHandler());

        MappingJackson2HttpMessageConverter jsonHttpMessageConverter = new MappingJackson2HttpMessageConverter();
        jsonHttpMessageConverter.getObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        kerberosRestTemplate.getMessageConverters().add(jsonHttpMessageConverter);
// Add CSRF header if required:
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Requested-By", "'username@domain");
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Client-Type","Web");
        headers.set("Client-UI-Component","Jim");


        HttpEntity<PostBody> postRequest = new HttpEntity<PostBody>(postRequestBody, headers);
        PostResponse pr = kerberosRestTemplate.postForObject("https://url.com/1/data/loadList", postRequest, PostResponse.class);

    }
}

package ErrorHandlers;

import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

import java.io.IOException;

public class KerberosRestTemplateResponseErrorHandler implements ResponseErrorHandler {
    @Override
    public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
        return (
                httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR
                        || httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR);
    }

    @Override
    public void handleError(ClientHttpResponse httpResponse) throws IOException {

        System.out.println("Error Response code " + httpResponse.getRawStatusCode());
        System.out.println(httpResponse.getStatusText());
        System.out.println(httpResponse.getBody().toString());
    }
}

Updated with Partial logs

1:56:58.233 [Finalizer] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager is shutting down 21:56:58.245 [Finalizer] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down 21:58:30.261 [main] DEBUG org.springframework.security.kerberos.client.KerberosRestTemplate - HTTP POST myendpoint.com 21:58:30.460 [main] DEBUG org.springframework.security.kerberos.client.KerberosRestTemplate - Accept=[application/json, application/*+json] 21:58:30.500 [main] DEBUG org.springframework.security.kerberos.client.KerberosRestTemplate - Writing [ClassPojo [firstWeekday = 0, metadata = [Ljava.lang.String;@2f465398, endDate = 2119-03-30, modifiedDate = 2019-07-20, aggregation = DAILY, symbols = [Ljava.lang.String;@548e6d58, startDate = 1900-03-30]] as "application/json" 21:58:30.540 [main] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default 21:58:30.561 [main] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context 21:58:30.565 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {s}->myendpoint.com:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20] 21:58:30.587 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->myendpoint.com:443][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20] 21:58:30.591 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {s}->myendpoint.com:443 21:58:30.617 [main] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to myendpoint.com:443 21:58:30.617 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Connecting socket to myendpoint.com:443 with timeout 0 21:58:30.747 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Enabled protocols: [TLSv1, TLSv1.1, TLSv1.2] 21:58:30.747 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Enabled cipher suites:[TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 21:58:30.747 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Starting handshake 21:58:30.923 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - Secure session established 21:58:30.923 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - negotiated protocol: TLSv1.2 21:58:30.924 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - negotiated cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 21:58:30.933 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - peer principal: CN=myendpoint.com, O=EXAMPLE p.l.c. 21:58:30.934 [main] DEBUG org.apache.http.conn.ssl.SSLConnectionSocketFactory - peer alternative names: [myendpoint.com]

21:58:30.962 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /1/data/loadList HTTP/1.1 21:58:30.963 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED 21:58:30.968 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED 21:58:30.976 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> POST /1/data/loadList HTTP/1.1 21:58:30.979 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept: application/json, application/+json 21:58:30.979 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Client-Type: Fred 21:58:30.980 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Type: application/json 21:58:30.981 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Client-UI-Component: Jim 21:58:30.981 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Length: 220 21:58:30.982 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Host: myendpoint.com 21:58:30.983 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Connection: Keep-Alive 21:58:30.983 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.9 (Java/1.8.0_212-3-redhat) 21:58:30.983 [main] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate 21:58:30.984 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "POST /1/data/loadList HTTP/1.1[\r][\n]" 21:58:30.984 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept: application/json, application/+json[\r][\n]" 21:58:30.984 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Client-Type: Fred[\r][\n]" 21:58:30.985 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Type: application/json[\r][\n]" 21:58:30.986 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Client-UI-Component: Jim[\r][\n]" 21:58:30.986 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 220[\r][\n]" 21:58:30.986 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Host: myendpoint.com[\r][\n]" 21:58:30.988 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]" 21:58:30.990 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.9 (Java/1.8.0_212-3-redhat)[\r][\n]" 21:58:30.990 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]" 21:58:30.991 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]" 21:58:30.992 [main] DEBUG org.apache.http.wire - http-outgoing-0 >> "{"firstWeekday":"0","metadata":["All"],"endDate":"2119-03-30","modifiedDate":"2019-07-20","aggregation":"DAILY","symbols":["symbol1","symbol2"],"startDate":"1900-03-30"}" 21:58:31.043 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 401 [\r][\n]"

21:58:31.043 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Access-Control-Allow-Credentials: true[\r][\n]" 21:58:31.043 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE[\r][\n]" 21:58:31.043 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Access-Control-Max-Age: 3600[\r][\n]" 21:58:31.043 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Access-Control-Allow-Headers: Client-Type, Content-Type, Accept, X-Requested-With, Authorization, rejectunauthorized[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "WWW-Authenticate: Negotiate[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "X-Content-Type-Options: nosniff[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "X-XSS-Protection: 1; mode=block[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Cache-Control: no-cache, no-store, max-age=0, must-revalidate[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Pragma: no-cache[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Expires: 0[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Strict-Transport-Security: max-age=31536000 ; includeSubDomains[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "X-Frame-Options: DENY[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Transfer-Encoding: chunked[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Date: Wed, 11 Sep 2019 20:58:31 GMT[\r][\n]" 21:58:31.044 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]" 21:58:31.050 [main] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 401

21:58:31.050 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Access-Control-Allow-Credentials: true 21:58:31.050 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Access-Control-Max-Age: 3600 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Access-Control-Allow-Headers: Client-Type, Content-Type, Accept, X-Requested-With, Authorization, rejectunauthorized 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << WWW-Authenticate: Negotiate 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << X-Content-Type-Options: nosniff 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << X-XSS-Protection: 1; mode=block 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Cache-Control: no-cache, no-store, max-age=0, must-revalidate 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Pragma: no-cache 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Expires: 0 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Strict-Transport-Security: max-age=31536000 ; includeSubDomains 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << X-Frame-Options: DENY 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Transfer-Encoding: chunked 21:58:31.051 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Date: Wed, 11 Sep 2019 20:58:31 GMT 21:58:31.063 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely 21:58:31.063 [main] DEBUG org.apache.http.impl.auth.HttpAuthenticator - Authentication required 21:58:31.063 [main] DEBUG org.apache.http.impl.auth.HttpAuthenticator - myendpoint.com:443 requested authentication 21:58:31.063 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Authentication schemes in the order of preference: [Negotiate, Kerberos, NTLM, CredSSP, Digest, Basic] 21:58:31.081 [main] DEBUG org.apache.http.impl.auth.SPNegoScheme - Received challenge '' from the auth server 21:58:31.082 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for Kerberos authentication scheme not available 21:58:31.083 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for NTLM authentication scheme not available 21:58:31.083 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for CredSSP authentication scheme not available 21:58:31.083 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for Digest authentication scheme not available 21:58:31.083 [main] DEBUG org.apache.http.impl.client.TargetAuthenticationStrategy - Challenge for Basic authentication scheme not available 21:58:31.093 [main] DEBUG org.springframework.security.kerberos.client.KerberosRestTemplate - Response 401 UNAUTHORIZED Error Response code 401

21:58:31.096 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "0[\r][\n]" 21:58:31.097 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]" 21:58:31.097 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->myendpoint.com:443] can be kept alive indefinitely 21:58:31.097 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0 21:58:31.097 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->myendpoint.com:443][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]

Process finished with exit code 0

mogoli
  • 2,153
  • 6
  • 26
  • 41

0 Answers0