X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fhttp%2Fclient%2FSpnegoAuthScheme.java;fp=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fhttp%2Fclient%2FSpnegoAuthScheme.java;h=7d5278ef06b90fb176c93ca35b582b8e18f41c55;hb=3714331f776988facff3632d86ad3f6d6352220c;hp=0000000000000000000000000000000000000000;hpb=c643dda1e6d1ccde18dc859ffae26d01cbbe87cf;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/http/client/SpnegoAuthScheme.java b/org.argeo.cms/src/org/argeo/cms/internal/http/client/SpnegoAuthScheme.java new file mode 100644 index 000000000..7d5278ef0 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/http/client/SpnegoAuthScheme.java @@ -0,0 +1,166 @@ +package org.argeo.cms.internal.http.client; + +import java.net.URL; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Base64; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; + +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.URIException; +import org.apache.commons.httpclient.auth.AuthPolicy; +import org.apache.commons.httpclient.auth.AuthScheme; +import org.apache.commons.httpclient.auth.AuthenticationException; +import org.apache.commons.httpclient.auth.CredentialsProvider; +import org.apache.commons.httpclient.auth.MalformedChallengeException; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.DefaultHttpParams; +import org.apache.commons.httpclient.params.HttpParams; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; + +/** Implementation of the SPNEGO auth scheme. */ +public class SpnegoAuthScheme implements AuthScheme { + private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class); + + public static final String NAME = "Negotiate"; + private final static Oid KERBEROS_OID; + static { + try { + KERBEROS_OID = new Oid("1.3.6.1.5.5.2"); + } catch (GSSException e) { + throw new IllegalStateException("Cannot create Kerberos OID", e); + } + } + + private boolean complete = false; + private String realm; + + @Override + public void processChallenge(String challenge) throws MalformedChallengeException { + log.debug("processChallenge " + challenge); + + } + + @Override + public String getSchemeName() { + return NAME; + } + + @Override + public String getParameter(String name) { + log.debug("getParameter " + name); + return null; + } + + @Override + public String getRealm() { + return realm; + } + + @Override + public String getID() { + return NAME; + } + + @Override + public boolean isConnectionBased() { + return true; + } + + @Override + public boolean isComplete() { + log.debug("isComplete"); + return complete; + } + + @Override + public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException { + log.debug("authenticate " + method + " " + uri); + return null; + } + + @Override + public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException { + log.debug("authenticate " + method); + GSSContext context = null; + String tokenStr = null; + String hostname; + try { + hostname = method.getURI().getHost(); + } catch (URIException e1) { + throw new IllegalStateException("Cannot authenticate", e1); + } + String serverPrinc = "HTTP@" + hostname; + + try { + // Get service's principal name + GSSManager manager = GSSManager.getInstance(); + GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID); + + // Get the context for authentication + context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME); + // context.requestMutualAuth(true); // Request mutual authentication + // context.requestConf(true); // Request confidentiality + context.requestCredDeleg(true); + + byte[] token = new byte[0]; + + // token is ignored on the first call + token = context.initSecContext(token, 0, token.length); + + // Send a token to the server if one was generated by + // initSecContext + if (token != null) { + tokenStr = Base64.getEncoder().encodeToString(token); + // complete=true; + } + return "Negotiate " + tokenStr; + } catch (GSSException e) { + throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e); + } + } + + public static void main(String[] args) { + if (args.length == 0) { + System.err.println("usage: java " + SpnegoAuthScheme.class.getName() + " "); + System.exit(1); + return; + } + String url = args[0]; + + URL jaasUrl = SpnegoAuthScheme.class.getResource("jaas.cfg"); + System.setProperty("java.security.auth.login.config", jaasUrl.toExternalForm()); + try { + LoginContext lc = new LoginContext("SINGLE_USER"); + lc.login(); + + AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class); + HttpParams params = DefaultHttpParams.getDefaultParams(); + ArrayList schemes = new ArrayList<>(); + schemes.add(SpnegoAuthScheme.NAME); + params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes); + params.setParameter(CredentialsProvider.PROVIDER, new SpnegoCredentialProvider()); + + int responseCode = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction() { + public Integer run() throws Exception { + HttpClient httpClient = new HttpClient(); + return httpClient.executeMethod(new GetMethod(url)); + } + }); + System.out.println("Reponse code: " + responseCode); + } catch (Exception e) { + e.printStackTrace(); + } + } + +}