1 package org
.argeo
.cms
.client
;
3 import java
.io
.BufferedInputStream
;
4 import java
.io
.IOException
;
5 import java
.net
.MalformedURLException
;
7 import java
.net
.http
.HttpClient
;
8 import java
.net
.http
.HttpRequest
;
9 import java
.net
.http
.HttpResponse
;
10 import java
.net
.http
.HttpResponse
.BodyHandler
;
11 import java
.net
.http
.HttpResponse
.BodyHandlers
;
12 import java
.nio
.file
.Files
;
13 import java
.nio
.file
.Path
;
14 import java
.nio
.file
.Paths
;
15 import java
.security
.KeyManagementException
;
16 import java
.security
.NoSuchAlgorithmException
;
17 import java
.security
.cert
.CertificateException
;
18 import java
.security
.cert
.CertificateFactory
;
19 import java
.security
.cert
.X509Certificate
;
20 import java
.util
.Collection
;
22 import javax
.net
.ssl
.SSLContext
;
23 import javax
.net
.ssl
.TrustManager
;
24 import javax
.net
.ssl
.X509TrustManager
;
25 import javax
.security
.auth
.Subject
;
26 import javax
.security
.auth
.login
.LoginContext
;
28 import org
.argeo
.cms
.auth
.ConsoleCallbackHandler
;
29 import org
.argeo
.cms
.auth
.RemoteAuthUtils
;
30 import org
.argeo
.util
.http
.HttpHeader
;
32 public class SpnegoHttpClient
{
33 public final static String CLIENT_LOGIN_CONTEXT
= "CLIENT";
35 public static void main(String
[] args
) throws MalformedURLException
{
36 // String principal = System.getProperty("javax.security.auth.login.name");
37 if (args
.length
== 0) {
38 System
.err
.println("usage: java -Djavax.security.auth.login.name=<principal@REALM> "
39 + SpnegoHttpClient
.class.getName() + " <url>");
45 String server
= u
.getHost();
47 URL jaasUrl
= SpnegoHttpClient
.class.getResource("jaas-client-ipa.cfg");
48 System
.setProperty("java.security.auth.login.config", jaasUrl
.toExternalForm());
50 LoginContext lc
= new LoginContext(CLIENT_LOGIN_CONTEXT
, new ConsoleCallbackHandler());
53 HttpClient httpClient
= openHttpClient(lc
.getSubject());
54 String token
= RemoteAuthUtils
.createGssToken(lc
.getSubject(), "HTTP", server
);
56 HttpRequest request
= HttpRequest
.newBuilder().uri(u
.toURI()) //
57 .header(HttpHeader
.AUTHORIZATION
.getHeaderName(), HttpHeader
.NEGOTIATE
+ " " + token
) //
59 BodyHandler
<String
> bodyHandler
= BodyHandlers
.ofString();
60 HttpResponse
<String
> response
= httpClient
.send(request
, bodyHandler
);
61 System
.out
.println(response
.body());
62 int responseCode
= response
.statusCode();
63 System
.exit(responseCode
);
64 } catch (Exception e
) {
69 static HttpClient
openHttpClient(Subject subject
) {
70 HttpClient client
= HttpClient
.newBuilder() //
71 .sslContext(ipaSslContext()) //
72 .version(HttpClient
.Version
.HTTP_1_1
) //
78 @SuppressWarnings("unchecked")
79 static SSLContext
ipaSslContext() {
81 final Collection
<X509Certificate
> certificates
;
82 Path caCertificatePath
= Paths
.get("/etc/ipa/ca.crt");
83 if (Files
.exists(caCertificatePath
)) {
84 CertificateFactory certificateFactory
= CertificateFactory
.getInstance("X509");
85 try (BufferedInputStream in
= new BufferedInputStream(Files
.newInputStream(caCertificatePath
))) {
86 certificates
= (Collection
<X509Certificate
>) certificateFactory
.generateCertificates(in
);
91 TrustManager
[] noopTrustManager
= new TrustManager
[] { new X509TrustManager() {
92 public void checkClientTrusted(X509Certificate
[] xcs
, String string
) {
95 public void checkServerTrusted(X509Certificate
[] xcs
, String string
) {
98 public X509Certificate
[] getAcceptedIssuers() {
99 if (certificates
== null)
101 return certificates
.toArray(new X509Certificate
[certificates
.size()]);
105 SSLContext sc
= SSLContext
.getInstance("ssl");
106 sc
.init(null, noopTrustManager
, null);
108 } catch (KeyManagementException
| NoSuchAlgorithmException
| CertificateException
| IOException e
) {
109 throw new IllegalStateException("Cannot create SSL context ", e
);