From 8320937d7248d4eb50d3db3f2ec205cd046e1ff7 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sun, 17 Jul 2022 15:33:31 +0200 Subject: [PATCH] Move legacy Apache HTTP Client from Argeo Commons --- Makefile | 2 +- .../httpclient3/HttpCredentialProvider.java | 20 ++ .../slc/cms/httpclient3/SpnegoAuthScheme.java | 179 ++++++++++++++++++ .../cms/httpclient3/SpnegoCredentials.java | 7 + .../org/argeo/slc/cms/httpclient3/jaas.cfg | 10 + 5 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java create mode 100644 cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java create mode 100644 cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java create mode 100644 cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg diff --git a/Makefile b/Makefile index d3fab4a46..08c9b8220 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ org.argeo.tp.jcr \ org.argeo.tp.formats \ org.argeo.tp.gis \ org.argeo.cms \ -org.argeo.cms.eclipse.rap \ +swt/rap/org.argeo.cms \ GRAALVM_HOME = /opt/graalvm-ce A2_BUNDLES_CLASSPATH = $(subst $(space),$(pathsep),$(strip $(A2_BUNDLES))) diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java new file mode 100644 index 000000000..59cfc4f55 --- /dev/null +++ b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/HttpCredentialProvider.java @@ -0,0 +1,20 @@ +package org.argeo.slc.cms.httpclient3; + +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.auth.AuthScheme; +import org.apache.commons.httpclient.auth.CredentialsNotAvailableException; +import org.apache.commons.httpclient.auth.CredentialsProvider; + +/** SPNEGO credential provider */ +public class HttpCredentialProvider implements CredentialsProvider { + + @Override + public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy) + throws CredentialsNotAvailableException { + if (scheme instanceof SpnegoAuthScheme) + return new SpnegoCredentials(); + else + throw new UnsupportedOperationException("Auth scheme " + scheme.getSchemeName() + " not supported"); + } + +} diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java new file mode 100644 index 000000000..61ae58b4a --- /dev/null +++ b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoAuthScheme.java @@ -0,0 +1,179 @@ +package org.argeo.slc.cms.httpclient3; + +import java.net.URL; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; + +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.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.HttpMethodParams; +import org.apache.commons.httpclient.params.HttpParams; +import org.argeo.cms.auth.RemoteAuthUtils; + +//// Register client-side SPNEGO auth scheme +//AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class); +//HttpParams params = DefaultHttpParams.getDefaultParams(); +//ArrayList schemes = new ArrayList<>(); +//schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred +//// schemes.add(AuthPolicy.BASIC);// incompatible with Basic +//params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes); +//params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider()); +//params.setParameter(HttpMethodParams.COOKIE_POLICY, KernelConstants.COOKIE_POLICY_BROWSER_COMPATIBILITY); +//// params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + + + +/** 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 final static String DEFAULT_KERBEROS_SERVICE = "HTTP"; + + private boolean complete = false; + private String realm; + + @Override + public void processChallenge(String challenge) throws MalformedChallengeException { + // if(tokenStr!=null){ + // log.error("Received challenge while there is a token. Failing."); + // complete = false; + // } + + } + + @Override + public String getSchemeName() { + return NAME; + } + + @Override + public String getParameter(String 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() { + return complete; + } + + @Override + public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException { + // log.debug("authenticate " + method + " " + uri); + // return null; + throw new UnsupportedOperationException(); + } + + @Override + public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException { +// GSSContext context = null; + String hostname; + try { + hostname = method.getURI().getHost(); + String tokenStr = RemoteAuthUtils.getGssToken(null, DEFAULT_KERBEROS_SERVICE, hostname); + return "Negotiate " + tokenStr; + } catch (Exception e1) { + complete = true; + throw new AuthenticationException("Cannot authenticate " + method, e1); + } +// String serverPrinc = DEFAULT_KERBEROS_SERVICE + "@" + 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; +// } +// } catch (GSSException e) { +// complete = true; +// throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e); +// } + } + + public static void main(String[] args) { + String principal = System.getProperty("javax.security.auth.login.name"); + if (args.length == 0 || principal == null) { + System.err.println("usage: java -Djavax.security.auth.login.name= " + + 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 HttpCredentialProvider()); + + 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(); + } + } + +} diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java new file mode 100644 index 000000000..06f6d5316 --- /dev/null +++ b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/SpnegoCredentials.java @@ -0,0 +1,7 @@ +package org.argeo.slc.cms.httpclient3; + +import org.apache.commons.httpclient.Credentials; + +public class SpnegoCredentials implements Credentials { + +} diff --git a/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg new file mode 100644 index 000000000..dc540ddb2 --- /dev/null +++ b/cms/org.argeo.slc.cms/src/org/argeo/slc/cms/httpclient3/jaas.cfg @@ -0,0 +1,10 @@ +SINGLE_USER { + com.sun.security.auth.module.Krb5LoginModule required + useTicketCache=true + debug=true; +}; + +com.sun.security.jgss.krb5.initiate { + com.sun.security.auth.module.Krb5LoginModule + required useTicketCache=true; +}; \ No newline at end of file -- 2.30.2