I am trying to implement a solution to access restapi which requires kerberos authentication and I am told you use a keytab file and service principal for this. I wrote some code to access the API and can see the request is reaching the server but is returning 401 unauthorized error response.
I even tried configuring the certificates in the truststore.jks and still not luck.
2023-03-13 15:07:32.446[0;39m [32mDEBUG[0;39m [35m27752[0;39m [2m---[0;39m [2m[ main][0;39m [36mo.s.s.k.client.KerberosRestTemplate [0;39m [2m:[0;39m HTTP GET https://kerberos-authenticator.xyz.com/odata/users
[2m2023-03-13 15:07:32.450[0;39m [32mDEBUG[0;39m [35m27752[0;39m [2m---[0;39m [2m[ main][0;39m [36mo.s.s.k.client.KerberosRestTemplate [0;39m [2m:[0;39m Accept=[text/plain, application/json, application/*+json, /] [2m2023-03-13 15:07:32.991[0;39m [32mDEBUG[0;39m [35m27752[0;39m [2m---[0;39m [2m[ main][0;39m [36mo.s.s.k.client.KerberosRestTemplate [0;39m [2m:[0;39m Response 401 UNAUTHORIZED Exception in thread "main" org.springframework.web.client.RestClientException: Error running rest call; nested exception is org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: [no body] at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:196) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717) at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:340) at com.xyz.restapi.SamplerestapiApplication.main(SamplerestapiApplication.java:43) Caused by: org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: [no body] at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:105) at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:168) at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122) at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:825) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:783) at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecuteSubject(KerberosRestTemplate.java:202) at org.springframework.security.kerberos.client.KerberosRestTemplate.access$100(KerberosRestTemplate.java:67) at org.springframework.security.kerberos.client.KerberosRestTemplate$1.run(KerberosRestTemplate.java:191) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:360) at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestTemplate.java:187) ... 3 more
Appreciate any help in resolving this.
below is the content of my krb5.conf
[libdefaults]
default_realm = I.XYZ.COM
[realms]
I.XYZ.COM = {
kdc = ldap.i.XYZ.com
admin_server = ldap.I.XYZ.com
}
[domain_realm]
.i.XYZ.com = I.XYZ.COM
i.XYZ.com = I.XYZ.COM
login.config
java-login {
com.sun.security.auth.module.Krb5LoginModule required
debug=true
useKeyTab=true
storeKey=true
useTicketCache=false
keyTab="C:/xyz/workspaces/sts/learning/src/main/resources/SVC.kerberos-c1.keytab"
principal="SVC.kerberos-c1@I.XYZ.COM";
};
@SpringBootApplication
public class SamplerestapiApplication {
static {
System.setProperty("java.security.krb5.conf", Paths.get("C:\\xyz\\workspaces\\sts\\samplerestapi\\src\\main\\resources\\krb5.conf").normalize().toAbsolutePath().toString());
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("http.use.global.creds", "false");
System.setProperty("java.security.auth.login.config", Paths.get("C:\\xyz\\workspaces\\sts\\samplerestapi\\src\\main\\resources\\login.config").normalize().toAbsolutePath().toString());
}
public static void main(String[] args) throws LoginException, MalformedURLException, GSSException, PrivilegedActionException, IOException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(SamplerestapiApplication.class, args);
RestTemplate restTemplate = applicationContext.getBean(RestTemplate.class);
String endpoint = "https://kerberos-authenticator.xyz.com/odata/users";
restTemplate.getForObject(endpoint, String.class);
}
}
@Configuration
public class AppConfig {
@Value("${app.service-principal}")
private String servicePrincipal;
@Value("${app.keytab-location}")
private String keytabLocation;
// @Value("${trust.store}")
// private Resource trustStore;
// @Value("${trust.store.password}")
// private String trustStorePassword;
@Bean
public RestTemplate restTemplate() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
// TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
// SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).setProtocol("TLSv1.2").build();
// SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
// CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
// HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// return new KerberosRestTemplate(keytabLocation, servicePrincipal,httpClient);
KerberosRestTemplate kerberosRestTemplate = new KerberosRestTemplate(keytabLocation,servicePrincipal);
SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustSelfSignedStrategy()).build();
HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
kerberosRestTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
return kerberosRestTemplate;
}
}