X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Fauth%2FUserAdminLoginModule.java;h=2faee6fa1157a5ed0c0e6a2af3da0bbefec9b6ae;hb=af92248d40838cc61209df352ea2d8d8142870cc;hp=3e44e65335bc9eb18e439b26e2722cbb4ea0241e;hpb=9dba7b01008499bdaf15c754190906d3200713fe;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 3e44e6533..2faee6fa1 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java @@ -1,35 +1,51 @@ package org.argeo.cms.auth; +import java.io.IOException; +import java.util.Iterator; +import java.util.Locale; import java.util.Map; +import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.LanguageCallback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.CredentialNotFoundException; +import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; +import org.argeo.cms.internal.kernel.Activator; +import org.argeo.eclipse.ui.specific.UiContext; import org.osgi.framework.BundleContext; +import org.osgi.service.http.HttpContext; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; public class UserAdminLoginModule implements LoginModule, AuthConstants { + private final static Log log = LogFactory + .getLog(UserAdminLoginModule.class); + private Subject subject; - private Map sharedState; private CallbackHandler callbackHandler; private boolean isAnonymous = false; - @SuppressWarnings("unchecked") + private HttpServletRequest request = null; + @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { try { this.subject = subject; - this.sharedState = (Map) sharedState; this.callbackHandler = callbackHandler; if (options.containsKey("anonymous")) isAnonymous = Boolean.parseBoolean(options.get("anonymous") @@ -41,55 +57,95 @@ public class UserAdminLoginModule implements LoginModule, AuthConstants { @Override public boolean login() throws LoginException { - BundleContext bc = (BundleContext) sharedState - .get(AuthConstants.BUNDLE_CONTEXT_KEY); + BundleContext bc = Activator.getBundleContext(); UserAdmin userAdmin = bc.getService(bc .getServiceReference(UserAdmin.class)); - Authorization authorization = (Authorization) sharedState - .get(AuthConstants.AUTHORIZATION_KEY); - if (authorization == null) - if (!isAnonymous) { - // ask for username and password - NameCallback nameCallback = new NameCallback("User"); - PasswordCallback passwordCallback = new PasswordCallback( - "Password", false); - - // handle callbacks - try { - callbackHandler.handle(new Callback[] { nameCallback, - passwordCallback }); - } catch (Exception e) { - throw new ArgeoException("Cannot handle callbacks", e); - } + Authorization authorization = null; + if (isAnonymous) { + authorization = userAdmin.getAuthorization(null); + } else { + HttpRequestCallback httpCallback = new HttpRequestCallback(); + // ask for username and password + NameCallback nameCallback = new NameCallback("User"); + PasswordCallback passwordCallback = new PasswordCallback( + "Password", false); + LanguageCallback langCallback = new LanguageCallback(); + try { + callbackHandler.handle(new Callback[] { httpCallback, + nameCallback, passwordCallback, langCallback }); + } catch (IOException e) { + throw new LoginException("Cannot handle http callback: " + + e.getMessage()); + } catch (ThreadDeath e) { + throw new ThreadDeathLoginException( + "Callbackhandler thread died", e); + } catch (UnsupportedCallbackException e) { + return false; + } + request = httpCallback.getRequest(); + if (request != null) { + authorization = (Authorization) request + .getAttribute(HttpContext.AUTHORIZATION); + if (authorization == null) + authorization = (Authorization) request.getSession() + .getAttribute(HttpContext.AUTHORIZATION); + } + + // i18n + Locale locale = langCallback.getLocale(); + if (locale == null) + locale = Locale.getDefault(); + UiContext.setLocale(locale); + if (authorization == null) { // create credentials final String username = nameCallback.getName(); - if (username == null || username.trim().equals("")) + if (username == null || username.trim().equals("")) { + // authorization = userAdmin.getAuthorization(null); throw new CredentialNotFoundException( "No credentials provided"); + } else { + char[] password = {}; + if (passwordCallback.getPassword() != null) + password = passwordCallback.getPassword(); + else + throw new CredentialNotFoundException( + "No credentials provided"); - char[] password = {}; - if (passwordCallback.getPassword() != null) - password = passwordCallback.getPassword(); - else - throw new CredentialNotFoundException( - "No credentials provided"); + User user = userAdmin.getUser(null, username); + if (user == null) + throw new FailedLoginException("Invalid credentials"); + if (!user.hasCredential(null, password)) + throw new FailedLoginException("Invalid credentials"); + // return false; + + // Log and monitor new login + if (log.isDebugEnabled()) + log.debug("Logged in to CMS with username [" + username+"]"); - User user = userAdmin.getUser(null, username); - if (user == null) - return false; - if (!user.hasCredential(null, password)) - return false; - authorization = userAdmin.getAuthorization(user); - } else { - authorization = userAdmin.getAuthorization(null); + authorization = userAdmin.getAuthorization(user); + } } + // } else { + // authorization = userAdmin.getAuthorization(null); + // } + } subject.getPrivateCredentials().add(authorization); return true; } @Override public boolean commit() throws LoginException { + Authorization authorization = subject + .getPrivateCredentials(Authorization.class).iterator().next(); + if (request != null && authorization.getName() != null) { + request.setAttribute(HttpContext.REMOTE_USER, + authorization.getName()); + request.setAttribute(HttpContext.AUTHORIZATION, authorization); + request.getSession().setAttribute(HttpContext.AUTHORIZATION, + authorization); + subject.getPrivateCredentials().add(request.getSession()); + } return true; } @@ -101,6 +157,15 @@ public class UserAdminLoginModule implements LoginModule, AuthConstants { @Override public boolean logout() throws LoginException { + Set httpSession = subject + .getPrivateCredentials(HttpSession.class); + Iterator it = httpSession.iterator(); + while (it.hasNext()) { + HttpSession sess = it.next(); + sess.setAttribute(HttpContext.AUTHORIZATION, null); + // sess.setMaxInactiveInterval(1);// invalidate session + } + subject.getPrivateCredentials().removeAll(httpSession); cleanUp(); return true; }