Refactor deploy properties and move legacy CMS exception.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / RemoteAuthUtils.java
index 6274bb146e736165214fcabd52f49c20edb3e5d8..0bb199dfdbfddcf4fb93eda4e4363834f9afa77b 100644 (file)
@@ -3,12 +3,19 @@ package org.argeo.cms.auth;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Base64;
 import java.util.function.Supplier;
 
 import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosTicket;
 
 import org.argeo.api.cms.CmsSession;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
+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;
 
 /** Remote authentication utilities. */
 public class RemoteAuthUtils {
@@ -59,4 +66,50 @@ public class RemoteAuthUtils {
                CmsSession cmsSession = CmsContextImpl.getCmsContext().getCmsSession(subject);
                return cmsSession;
        }
+
+       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);
+               }
+       }
+
+       public static String getGssToken(Subject subject, String serverPrinc) {
+               if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty())
+                       throw new IllegalArgumentException("Subject " + subject + " is not GSS authenticated.");
+               return Subject.doAs(subject, (PrivilegedAction<String>) () -> {
+                       GSSContext context = null;
+                       String tokenStr = null;
+
+                       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 tokenStr;
+
+                       } catch (GSSException e) {
+                               throw new IllegalStateException("Cannot authenticate to " + serverPrinc, e);
+                       }
+               });
+       }
 }