+ // thread already logged in
+ if (SecurityContextHolder.getContext().getAuthentication() != null)
+ return super.login();
+
+ if (remote && anonymous)
+ throw new LoginException(
+ "Cannot have a Spring login module which is remote and anonymous");
+
+ // 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();
+
+ // deals first with public access since it's simple
+ if (anonymous) {
+ // TODO integrate with JCR?
+ Object principal = UUID.randomUUID().toString();
+ GrantedAuthority[] authorities = { new GrantedAuthorityImpl(
+ anonymousRole) };
+ AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
+ key, principal, authorities);
+ Authentication auth = authenticationManager
+ .authenticate(anonymousToken);
+ registerAuthentication(auth);
+ return super.login();
+ }
+
+ if (callbackHandler == null)
+ throw new LoginException("No call back handler available");
+
+ // ask for username and password
+ NameCallback nameCallback = new NameCallback("User");
+ PasswordCallback passwordCallback = new PasswordCallback(
+ "Password", false);
+ final String defaultNodeUrl = "http://localhost:7070/org.argeo.jcr.webapp/remoting/node";
+ final String defaultSecurityWorkspace = "security";
+ NameCallback urlCallback = new NameCallback("Site URL",
+ defaultNodeUrl);
+ NameCallback securityWorkspaceCallback = new NameCallback(
+ "Security Workspace", defaultSecurityWorkspace);
+
+ // handle callbacks
+ if (remote)
+ callbackHandler.handle(new Callback[] { nameCallback,
+ passwordCallback, urlCallback,
+ securityWorkspaceCallback });
+ else
+ callbackHandler.handle(new Callback[] { nameCallback,
+ passwordCallback });
+
+ // create credentials
+ String username = nameCallback.getName();
+ if (username == null || username.trim().equals(""))
+ return false;
+
+ String password = "";
+ if (passwordCallback.getPassword() != null)
+ password = String.valueOf(passwordCallback.getPassword());
+
+ NodeAuthenticationToken credentials;
+ if (remote) {
+ String url = urlCallback.getName();
+ String workspace = securityWorkspaceCallback.getName();
+ credentials = new NodeAuthenticationToken(username, password,
+ url, workspace);
+ } else {
+ credentials = new NodeAuthenticationToken(username, password);
+ }
+
+ Authentication authentication;
+ try {
+ authentication = authenticationManager
+ .authenticate(credentials);
+ } catch (BadCredentialsException e) {
+ // wait between failed login attempts
+ Thread.sleep(waitBetweenFailedLoginAttempts);
+ throw e;
+ }