Introduce CMS event bus and use it in UI.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / RemoteAuthUtils.java
index 0bb199dfdbfddcf4fb93eda4e4363834f9afa77b..757bf73bfc43513fab8c004aaa3eb363a005f22a 100644 (file)
@@ -8,9 +8,14 @@ import java.util.function.Supplier;
 
 import javax.security.auth.Subject;
 import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
 
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
+import org.argeo.util.http.HttpHeader;
 import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.GSSManager;
@@ -19,8 +24,20 @@ import org.ietf.jgss.Oid;
 
 /** Remote authentication utilities. */
 public class RemoteAuthUtils {
+       private final static CmsLog log = CmsLog.getLog(RemoteAuthUtils.class);
+
        static final String REMOTE_USER = "org.osgi.service.http.authentication.remote.user";
-//     private static BundleContext bundleContext = FrameworkUtil.getBundle(RemoteAuthUtils.class).getBundleContext();
+       private final static Oid KERBEROS_OID;
+//     private final static Oid KERB_V5_OID, KRB5_PRINCIPAL_NAME_OID;
+       static {
+               try {
+                       KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
+//                     KERB_V5_OID = new Oid("1.2.840.113554.1.2.2");
+//                     KRB5_PRINCIPAL_NAME_OID = new Oid("1.2.840.113554.1.2.2.1");
+               } catch (GSSException e) {
+                       throw new IllegalStateException("Cannot create Kerberos OID", e);
+               }
+       }
 
        /**
         * Execute this supplier, using the CMS class loader as context classloader.
@@ -67,26 +84,21 @@ public class RemoteAuthUtils {
                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) {
+       public static String getGssToken(Subject subject, String service, String server) {
                if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty())
                        throw new IllegalArgumentException("Subject " + subject + " is not GSS authenticated.");
                return Subject.doAs(subject, (PrivilegedAction<String>) () -> {
+                       // !! different format than Kerberos
+                       String serverPrinc = service + "@" + server;
                        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);
+                               // GSSName serverName = manager.createName(serverPrinc,
+                               // GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
+                               GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE);
 
                                // Get the context for authentication
                                context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
@@ -112,4 +124,48 @@ public class RemoteAuthUtils {
                        }
                });
        }
+
+       public static LoginContext anonymousLogin(RemoteAuthRequest remoteAuthRequest,
+                       RemoteAuthResponse remoteAuthResponse) {
+               // anonymous
+               ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
+               try {
+                       Thread.currentThread().setContextClassLoader(RemoteAuthUtils.class.getClassLoader());
+                       LoginContext lc = CmsAuth.ANONYMOUS
+                                       .newLoginContext(new RemoteAuthCallbackHandler(remoteAuthRequest, remoteAuthResponse));
+                       lc.login();
+                       return lc;
+               } catch (LoginException e1) {
+                       if (log.isDebugEnabled())
+                               log.error("Cannot log in as anonymous", e1);
+                       return null;
+               } finally {
+                       Thread.currentThread().setContextClassLoader(currentContextClassLoader);
+               }
+       }
+
+       public static int askForWwwAuth(RemoteAuthResponse remoteAuthResponse, String realm, boolean forceBasic) {
+               // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic
+               // realm=\"" + httpAuthRealm + "\"");
+               if (hasAcceptorCredentials() && !forceBasic)// SPNEGO
+                       remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getName(), HttpHeader.NEGOTIATE);
+               else
+                       remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getName(),
+                                       HttpHeader.BASIC + " " + HttpHeader.REALM + "=\"" + realm + "\"");
+
+               // response.setDateHeader("Date", System.currentTimeMillis());
+               // response.setDateHeader("Expires", System.currentTimeMillis() + (24 *
+               // 60 * 60 * 1000));
+               // response.setHeader("Accept-Ranges", "bytes");
+               // response.setHeader("Connection", "Keep-Alive");
+               // response.setHeader("Keep-Alive", "timeout=5, max=97");
+               // response.setContentType("text/html; charset=UTF-8");
+
+               return 401;
+       }
+
+       private static boolean hasAcceptorCredentials() {
+               return CmsContextImpl.getCmsContext().getAcceptorCredentials() != null;
+       }
+
 }