X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=security%2Fplugins%2Forg.argeo.security.equinox%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fequinox%2FSpringLoginModule.java;h=dada3440525caf6c95b3e0172c25c33201223713;hb=8b8ee149b20e2578a55e17413fa5f7399ff7ba14;hp=c35416d9979c9fe246b9be4621a6bc233d714cff;hpb=149023e5969377045847bbecf24b0898b18a67a9;p=lgpl%2Fargeo-commons.git diff --git a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java index c35416d99..dada34405 100644 --- a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java +++ b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java @@ -7,7 +7,6 @@ import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.TextOutputCallback; import javax.security.auth.login.LoginException; import org.apache.commons.logging.Log; @@ -15,11 +14,14 @@ import org.apache.commons.logging.LogFactory; import org.argeo.security.SiteAuthenticationToken; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationManager; +import org.springframework.security.BadCredentialsException; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.providers.jaas.SecurityContextLoginModule; /** Login module which caches one subject per thread. */ public class SpringLoginModule extends SecurityContextLoginModule { + final static String NODE_REPO_URI = "argeo.node.repo.uri"; + private final static Log log = LogFactory.getLog(SpringLoginModule.class); private AuthenticationManager authenticationManager; @@ -28,6 +30,10 @@ public class SpringLoginModule extends SecurityContextLoginModule { private Subject subject; + private Long waitBetweenFailedLoginAttempts = 5 * 1000l; + + private Boolean remote = false; + public SpringLoginModule() { } @@ -41,75 +47,83 @@ public class SpringLoginModule extends SecurityContextLoginModule { } public boolean login() throws LoginException { - // try to retrieve Authentication from Subject - // Set auths = - // subject.getPrincipals(Authentication.class); - // if (auths.size() > 0) - // SecurityContextHolder.getContext().setAuthentication( - // auths.iterator().next()); - - // thread already logged in - if (SecurityContextHolder.getContext().getAuthentication() != null) - return super.login(); - - // reset all principals and credentials - if (log.isTraceEnabled()) - log.trace("Resetting all principals and credentials of " + subject); - if (subject.getPrincipals() != null) - subject.getPrincipals().clear(); - if (subject.getPrivateCredentials() != null) - subject.getPrivateCredentials().clear(); - if (subject.getPublicCredentials() != null) - subject.getPublicCredentials().clear(); - - // ask for username and password - Callback label = new TextOutputCallback(TextOutputCallback.INFORMATION, - "Required login"); - NameCallback nameCallback = new NameCallback("User"); - PasswordCallback passwordCallback = new PasswordCallback("Password", - false); - - // NameCallback urlCallback = new NameCallback("Site URL"); - - if (callbackHandler == null) { - throw new LoginException("No call back handler available"); - // return false; - } try { - callbackHandler.handle(new Callback[] { label, nameCallback, - passwordCallback }); + // thread already logged in + if (SecurityContextHolder.getContext().getAuthentication() != null) + return super.login(); + + // reset all principals and credentials + if (log.isTraceEnabled()) + log.trace("Resetting all principals and credentials of " + + subject); + if (subject.getPrincipals() != null) + subject.getPrincipals().clear(); + if (subject.getPrivateCredentials() != null) + subject.getPrivateCredentials().clear(); + if (subject.getPublicCredentials() != null) + subject.getPublicCredentials().clear(); + + // ask for username and password + NameCallback nameCallback = new NameCallback("User"); + PasswordCallback passwordCallback = new PasswordCallback( + "Password", false); + + NameCallback urlCallback = new NameCallback("Site URL"); + + if (callbackHandler == null) + throw new LoginException("No call back handler available"); + if (remote) + callbackHandler.handle(new Callback[] { nameCallback, + passwordCallback, urlCallback }); + else + callbackHandler.handle(new Callback[] { nameCallback, + passwordCallback }); + + // Set user name and password + String username = nameCallback.getName(); + if (username == null || username.trim().equals("")) + return false; + + String password = ""; + if (passwordCallback.getPassword() != null) + password = String.valueOf(passwordCallback.getPassword()); + + String url = remote ? urlCallback.getName() : null; + if (remote && (url == null || url.trim().equals(""))) + // for convenience, may be removed in the future + url = System.getProperty(NODE_REPO_URI); + + // TODO: set it via system properties + String workspace = null; + + SiteAuthenticationToken credentials = new SiteAuthenticationToken( + username, password, url, workspace); + + Authentication authentication; + try { + authentication = authenticationManager + .authenticate(credentials); + } catch (BadCredentialsException e) { + // wait between failed login attempts + Thread.sleep(waitBetweenFailedLoginAttempts); + throw e; + } + registerAuthentication(authentication); + boolean res = super.login(); + return res; + } catch (LoginException e) { + throw e; + } catch (ThreadDeath e) { + LoginException le = new LoginException( + "Spring Security login thread died"); + le.initCause(e); + throw le; } catch (Exception e) { - throw new RuntimeException("Unexpected exception when handling", e); + LoginException le = new LoginException( + "Spring Security login failed"); + le.initCause(e); + throw le; } - - // Set user name and password - String username = nameCallback.getName(); - String password = ""; - if (passwordCallback.getPassword() != null) { - password = String.valueOf(passwordCallback.getPassword()); - } - - // String url = urlCallback.getName(); - // TODO: set it via system properties - String workspace = null; - - SiteAuthenticationToken credentials = new SiteAuthenticationToken( - username, password, null, workspace); - - // try { - Authentication authentication = authenticationManager - .authenticate(credentials); - registerAuthentication(authentication); - boolean res = super.login(); - return res; - // } catch (BadCredentialsException bce) { - // throw bce; - // } catch (LoginException e) { - // // LoginException loginException = new LoginException( - // // "Bad credentials"); - // // loginException.initCause(e); - // throw e; - // } } @Override @@ -133,4 +147,8 @@ public class SpringLoginModule extends SecurityContextLoginModule { AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } + + public void setRemote(Boolean remote) { + this.remote = remote; + } }