I'm writing HTTP connection with Kerberos authentication. I have "HTTP/1.1 401 Unauthorized". Could you recommend me what I should check? I think there's somethink trick, but I don't see it.
May be I should set header "WWW-Authenticate" with "Negotiate"?
Thank a lot in advanced for any help and ideas.
public class ClientKerberosAuthentication {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.auth.login.config", "login.conf");
System.setProperty("java.security.krb5.conf", "krb5.conf");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
NegotiateSchemeFactory nsf = new NegotiateSchemeFactory();
httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf);
List<String> authpref = new ArrayList<String>();
authpref.add(AuthPolicy.BASIC);
authpref.add(AuthPolicy.SPNEGO);
httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, AuthScope.ANY_REALM, AuthPolicy.SPNEGO),
new UsernamePasswordCredentials("myuser", "mypass"));
System.out.println("----------------------------------------");
HttpUriRequest request = new HttpGet("http://localhost:8084/web-app/webdav/213/_test.docx");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println("----------------------------------------");
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
System.out.println("----------------------------------------");
// This ensures the connection gets released back to the manager
EntityUtils.consume(entity);
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
SPNEGO will not work because you use
localhost
as URL hostname.Your server is configured for a set of SPNs (or at least one) beginning with
HTTP/
registered on the ActiveDirectory service account. You can query them from AD thanks tosetspn -l yourServiceAccount
.Your URL must use an effective server hostname known as SPN in ActiveDirectory so that Apache Http Client can negotiate a TGS for this service and send it to your server.
I had the same problem and just found your post. I bookmarked it so I can post an answer when I fixed it. I post a link to my question where someone answered it, so if someone finds this via Google they find the answer:
HttpClient has problem creating the SPN for the AD when the URL has a port.
See my question + answer here: HttpClient check Kerberos secured webpage. NTLM login didn't work
Here is a test client I wrote in my project. This client relies on all encryption types to be enabled on JDK,
If you see following in your logs and your keytab is encrypted at 256 bit default etypes for
default_tkt_enctypes: 17 16 23 1 3.
then following jar http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html needs to be downloaded and placed in
JDK/jre/lib/security
to enable AES256 bit encryption after that you should see following in logs default etypes fordefault_tkt_enctypes: 18 17 16 23 1 3.
Utility class