1 package org
.argeo
.cms
.auth
;
3 import java
.security
.AccessControlContext
;
4 import java
.security
.AccessController
;
5 import java
.security
.PrivilegedAction
;
6 import java
.util
.Base64
;
7 import java
.util
.function
.Supplier
;
9 import javax
.security
.auth
.Subject
;
10 import javax
.security
.auth
.kerberos
.KerberosTicket
;
12 import org
.argeo
.api
.cms
.CmsSession
;
13 import org
.argeo
.cms
.internal
.runtime
.CmsContextImpl
;
14 import org
.ietf
.jgss
.GSSContext
;
15 import org
.ietf
.jgss
.GSSException
;
16 import org
.ietf
.jgss
.GSSManager
;
17 import org
.ietf
.jgss
.GSSName
;
18 import org
.ietf
.jgss
.Oid
;
20 /** Remote authentication utilities. */
21 public class RemoteAuthUtils
{
22 static final String REMOTE_USER
= "org.osgi.service.http.authentication.remote.user";
23 private final static Oid KERBEROS_OID
;
24 // private final static Oid KERB_V5_OID, KRB5_PRINCIPAL_NAME_OID;
27 KERBEROS_OID
= new Oid("1.3.6.1.5.5.2");
28 // KERB_V5_OID = new Oid("1.2.840.113554.1.2.2");
29 // KRB5_PRINCIPAL_NAME_OID = new Oid("1.2.840.113554.1.2.2.1");
30 } catch (GSSException e
) {
31 throw new IllegalStateException("Cannot create Kerberos OID", e
);
36 * Execute this supplier, using the CMS class loader as context classloader.
37 * Useful to log in to JCR.
39 public final static <T
> T
doAs(Supplier
<T
> supplier
, RemoteAuthRequest req
) {
40 ClassLoader currentContextCl
= Thread
.currentThread().getContextClassLoader();
41 Thread
.currentThread().setContextClassLoader(RemoteAuthUtils
.class.getClassLoader());
44 Subject
.getSubject((AccessControlContext
) req
.getAttribute(AccessControlContext
.class.getName())),
45 new PrivilegedAction
<T
>() {
49 return supplier
.get();
54 Thread
.currentThread().setContextClassLoader(currentContextCl
);
58 public final static void configureRequestSecurity(RemoteAuthRequest req
) {
59 if (req
.getAttribute(AccessControlContext
.class.getName()) != null)
60 throw new IllegalStateException("Request already authenticated.");
61 AccessControlContext acc
= AccessController
.getContext();
62 req
.setAttribute(REMOTE_USER
, CurrentUser
.getUsername());
63 req
.setAttribute(AccessControlContext
.class.getName(), acc
);
66 public final static void clearRequestSecurity(RemoteAuthRequest req
) {
67 if (req
.getAttribute(AccessControlContext
.class.getName()) == null)
68 throw new IllegalStateException("Cannot clear non-authenticated request.");
69 req
.setAttribute(REMOTE_USER
, null);
70 req
.setAttribute(AccessControlContext
.class.getName(), null);
73 public static CmsSession
getCmsSession(RemoteAuthRequest req
) {
74 Subject subject
= Subject
75 .getSubject((AccessControlContext
) req
.getAttribute(AccessControlContext
.class.getName()));
76 CmsSession cmsSession
= CmsContextImpl
.getCmsContext().getCmsSession(subject
);
80 public static String
getGssToken(Subject subject
, String service
, String server
) {
81 if (subject
.getPrivateCredentials(KerberosTicket
.class).isEmpty())
82 throw new IllegalArgumentException("Subject " + subject
+ " is not GSS authenticated.");
83 return Subject
.doAs(subject
, (PrivilegedAction
<String
>) () -> {
84 // !! different format than Kerberos
85 String serverPrinc
= service
+ "@" + server
;
86 GSSContext context
= null;
87 String tokenStr
= null;
90 // Get service's principal name
91 GSSManager manager
= GSSManager
.getInstance();
92 GSSName serverName
= manager
.createName(serverPrinc
, GSSName
.NT_HOSTBASED_SERVICE
, KERBEROS_OID
);
94 // Get the context for authentication
95 context
= manager
.createContext(serverName
, KERBEROS_OID
, null, GSSContext
.DEFAULT_LIFETIME
);
96 // context.requestMutualAuth(true); // Request mutual authentication
97 // context.requestConf(true); // Request confidentiality
98 context
.requestCredDeleg(true);
100 byte[] token
= new byte[0];
102 // token is ignored on the first call
103 token
= context
.initSecContext(token
, 0, token
.length
);
105 // Send a token to the server if one was generated by
108 tokenStr
= Base64
.getEncoder().encodeToString(token
);
113 } catch (GSSException e
) {
114 throw new IllegalStateException("Cannot authenticate to " + serverPrinc
, e
);