X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Fauth%2FUserAdminLoginModule.java;h=7297513c2849afe1ab98a2af95ef83691a27df48;hb=31d7eccd2b0effdadaaa5b6349e5b6b6ea753e3c;hp=e39918e4002d40d18584ad91819a2a86545c92e5;hpb=54e74b900b1c0f7b1de0def771de35e50a8d4071;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java index e39918e40..7297513c2 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java @@ -1,8 +1,9 @@ package org.argeo.cms.auth; +import static org.argeo.naming.LdapAttrs.cn; + import java.io.IOException; import java.security.PrivilegedAction; -import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -29,12 +30,17 @@ import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; import org.argeo.cms.internal.kernel.Activator; import org.argeo.naming.LdapAttrs; +import org.argeo.node.NodeConstants; +import org.argeo.node.security.CryptoKeyring; import org.argeo.osgi.useradmin.AuthenticatingUser; import org.argeo.osgi.useradmin.IpaUtils; import org.argeo.osgi.useradmin.OsUserUtils; +import org.argeo.osgi.useradmin.TokenUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; import org.osgi.service.useradmin.Authorization; +import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; @@ -73,10 +79,10 @@ public class UserAdminLoginModule implements LoginModule { @Override public boolean login() throws LoginException { - UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class)); + UserAdmin userAdmin = Activator.getUserAdmin(); final String username; final char[] password; - X509Certificate[] certificateChain = null; + Object certificateChain = null; if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME) && sharedState.containsKey(CmsAuthUtils.SHARED_STATE_PWD)) { // NB: required by Basic http auth @@ -85,9 +91,17 @@ public class UserAdminLoginModule implements LoginModule { // // TODO locale? } else if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME) && sharedState.containsKey(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN)) { - // NB: required by Basic http auth - username = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME); - certificateChain = (X509Certificate[]) sharedState.get(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN); + String certDn = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME); +// LdapName ldapName; +// try { +// ldapName = new LdapName(certificateName); +// } catch (InvalidNameException e) { +// e.printStackTrace(); +// return false; +// } +// username = ldapName.getRdn(ldapName.size() - 1).getValue().toString(); + username = certDn; + certificateChain = sharedState.get(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN); password = null; } else if (singleUser) { username = OsUserUtils.getOsUsername(); @@ -122,8 +136,25 @@ public class UserAdminLoginModule implements LoginModule { password = passwordCallback.getPassword(); else throw new CredentialNotFoundException("No credentials provided"); + sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, username); + sharedState.put(CmsAuthUtils.SHARED_STATE_PWD, password); } User user = searchForUser(userAdmin, username); + + // Tokens + if (user == null) { + String token = username; + Group tokenGroup = searchForToken(userAdmin, token); + if (tokenGroup != null) { + Authorization tokenAuthorization = getAuthorizationFromToken(userAdmin, tokenGroup); + if (tokenAuthorization != null) { + bindAuthorization = tokenAuthorization; + authenticatedUser = (User) userAdmin.getRole(bindAuthorization.getName()); + return true; + } + } + } + if (user == null) return true;// expect Kerberos @@ -163,10 +194,15 @@ public class UserAdminLoginModule implements LoginModule { @Override public boolean commit() throws LoginException { + if (locale == null) + subject.getPublicCredentials().add(Locale.getDefault()); + else + subject.getPublicCredentials().add(locale); + if (singleUser) { OsUserUtils.loginAsSystemUser(subject); } - UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class)); + UserAdmin userAdmin = Activator.getUserAdmin(); Authorization authorization; if (callbackHandler == null) {// anonymous authorization = userAdmin.getAuthorization(null); @@ -204,9 +240,38 @@ public class UserAdminLoginModule implements LoginModule { throw new LoginException( "User admin found no authorization for authenticated user " + authenticatingUser.getName()); } + // Log and monitor new login - CmsAuthUtils.addAuthorization(subject, authorization, locale, - (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST)); + HttpServletRequest request = (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST); + CmsAuthUtils.addAuthorization(subject, authorization, locale, request); + + // Unlock keyring (underlying login to the JCR repository) + char[] password = (char[]) sharedState.get(CmsAuthUtils.SHARED_STATE_PWD); + if (password != null) { + ServiceReference keyringSr = bc.getServiceReference(CryptoKeyring.class); + if (keyringSr != null) { + CryptoKeyring keyring = bc.getService(keyringSr); + Subject.doAs(subject, new PrivilegedAction() { + + @Override + public Void run() { + try { + keyring.unlock(password); + } catch (Exception e) { + e.printStackTrace(); + log.warn("Could not unlock keyring with the password provided by " + authorization.getName() + + ": " + e.getMessage()); + } + return null; + } + + }); + } + } + + // Register CmsSession with initial subject + CmsAuthUtils.registerSessionAuthorization(request, subject, authorization, locale); + if (log.isDebugEnabled()) log.debug("Logged in to CMS: " + subject); return true; @@ -261,4 +326,26 @@ public class UserAdminLoginModule implements LoginModule { } } + + protected Group searchForToken(UserAdmin userAdmin, String token) { + String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN; + Group tokenGroup = (Group) userAdmin.getRole(dn); + return tokenGroup; + } + + protected Authorization getAuthorizationFromToken(UserAdmin userAdmin, Group tokenGroup) { + if (TokenUtils.isExpired(tokenGroup)) + return null; +// String expiryDateStr = (String) tokenGroup.getProperties().get(description.name()); +// if (expiryDateStr != null) { +// Instant expiryDate = NamingUtils.ldapDateToInstant(expiryDateStr); +// if (expiryDate.isBefore(Instant.now())) { +// if (log.isDebugEnabled()) +// log.debug("Token " + tokenGroup.getName() + " has expired."); +// return null; +// } +// } + Authorization auth = userAdmin.getAuthorization(tokenGroup); + return auth; + } }