]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/http/client/SpnegoAuthScheme.java
SPNEGO support
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / http / client / SpnegoAuthScheme.java
1 package org.argeo.cms.internal.http.client;
2
3 import java.net.URL;
4 import java.security.PrivilegedExceptionAction;
5 import java.util.ArrayList;
6 import java.util.Base64;
7
8 import javax.security.auth.Subject;
9 import javax.security.auth.login.LoginContext;
10
11 import org.apache.commons.httpclient.Credentials;
12 import org.apache.commons.httpclient.HttpClient;
13 import org.apache.commons.httpclient.HttpMethod;
14 import org.apache.commons.httpclient.URIException;
15 import org.apache.commons.httpclient.auth.AuthPolicy;
16 import org.apache.commons.httpclient.auth.AuthScheme;
17 import org.apache.commons.httpclient.auth.AuthenticationException;
18 import org.apache.commons.httpclient.auth.CredentialsProvider;
19 import org.apache.commons.httpclient.auth.MalformedChallengeException;
20 import org.apache.commons.httpclient.methods.GetMethod;
21 import org.apache.commons.httpclient.params.DefaultHttpParams;
22 import org.apache.commons.httpclient.params.HttpParams;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.ietf.jgss.GSSContext;
26 import org.ietf.jgss.GSSException;
27 import org.ietf.jgss.GSSManager;
28 import org.ietf.jgss.GSSName;
29 import org.ietf.jgss.Oid;
30
31 /** Implementation of the SPNEGO auth scheme. */
32 public class SpnegoAuthScheme implements AuthScheme {
33 private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class);
34
35 public static final String NAME = "Negotiate";
36 private final static Oid KERBEROS_OID;
37 static {
38 try {
39 KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
40 } catch (GSSException e) {
41 throw new IllegalStateException("Cannot create Kerberos OID", e);
42 }
43 }
44
45 private boolean complete = false;
46 private String realm;
47
48 @Override
49 public void processChallenge(String challenge) throws MalformedChallengeException {
50 log.debug("processChallenge " + challenge);
51
52 }
53
54 @Override
55 public String getSchemeName() {
56 return NAME;
57 }
58
59 @Override
60 public String getParameter(String name) {
61 log.debug("getParameter " + name);
62 return null;
63 }
64
65 @Override
66 public String getRealm() {
67 return realm;
68 }
69
70 @Override
71 public String getID() {
72 return NAME;
73 }
74
75 @Override
76 public boolean isConnectionBased() {
77 return true;
78 }
79
80 @Override
81 public boolean isComplete() {
82 log.debug("isComplete");
83 return complete;
84 }
85
86 @Override
87 public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
88 log.debug("authenticate " + method + " " + uri);
89 return null;
90 }
91
92 @Override
93 public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
94 log.debug("authenticate " + method);
95 GSSContext context = null;
96 String tokenStr = null;
97 String hostname;
98 try {
99 hostname = method.getURI().getHost();
100 } catch (URIException e1) {
101 throw new IllegalStateException("Cannot authenticate", e1);
102 }
103 String serverPrinc = "HTTP@" + hostname;
104
105 try {
106 // Get service's principal name
107 GSSManager manager = GSSManager.getInstance();
108 GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
109
110 // Get the context for authentication
111 context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
112 // context.requestMutualAuth(true); // Request mutual authentication
113 // context.requestConf(true); // Request confidentiality
114 context.requestCredDeleg(true);
115
116 byte[] token = new byte[0];
117
118 // token is ignored on the first call
119 token = context.initSecContext(token, 0, token.length);
120
121 // Send a token to the server if one was generated by
122 // initSecContext
123 if (token != null) {
124 tokenStr = Base64.getEncoder().encodeToString(token);
125 // complete=true;
126 }
127 return "Negotiate " + tokenStr;
128 } catch (GSSException e) {
129 throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e);
130 }
131 }
132
133 public static void main(String[] args) {
134 if (args.length == 0) {
135 System.err.println("usage: java " + SpnegoAuthScheme.class.getName() + " <url>");
136 System.exit(1);
137 return;
138 }
139 String url = args[0];
140
141 URL jaasUrl = SpnegoAuthScheme.class.getResource("jaas.cfg");
142 System.setProperty("java.security.auth.login.config", jaasUrl.toExternalForm());
143 try {
144 LoginContext lc = new LoginContext("SINGLE_USER");
145 lc.login();
146
147 AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
148 HttpParams params = DefaultHttpParams.getDefaultParams();
149 ArrayList<String> schemes = new ArrayList<>();
150 schemes.add(SpnegoAuthScheme.NAME);
151 params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
152 params.setParameter(CredentialsProvider.PROVIDER, new SpnegoCredentialProvider());
153
154 int responseCode = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Integer>() {
155 public Integer run() throws Exception {
156 HttpClient httpClient = new HttpClient();
157 return httpClient.executeMethod(new GetMethod(url));
158 }
159 });
160 System.out.println("Reponse code: " + responseCode);
161 } catch (Exception e) {
162 e.printStackTrace();
163 }
164 }
165
166 }