1 package org
.argeo
.security
.equinox
;
5 import javax
.security
.auth
.Subject
;
6 import javax
.security
.auth
.callback
.Callback
;
7 import javax
.security
.auth
.callback
.CallbackHandler
;
8 import javax
.security
.auth
.callback
.NameCallback
;
9 import javax
.security
.auth
.callback
.PasswordCallback
;
10 import javax
.security
.auth
.login
.LoginException
;
12 import org
.apache
.commons
.logging
.Log
;
13 import org
.apache
.commons
.logging
.LogFactory
;
14 import org
.argeo
.security
.NodeAuthenticationToken
;
15 import org
.springframework
.security
.Authentication
;
16 import org
.springframework
.security
.AuthenticationManager
;
17 import org
.springframework
.security
.BadCredentialsException
;
18 import org
.springframework
.security
.context
.SecurityContextHolder
;
19 import org
.springframework
.security
.providers
.jaas
.SecurityContextLoginModule
;
21 /** Login module which caches one subject per thread. */
22 public class SpringLoginModule
extends SecurityContextLoginModule
{
23 final static String NODE_REPO_URI
= "argeo.node.repo.uri";
25 private final static Log log
= LogFactory
.getLog(SpringLoginModule
.class);
27 private AuthenticationManager authenticationManager
;
29 private CallbackHandler callbackHandler
;
31 private Subject subject
;
33 private Long waitBetweenFailedLoginAttempts
= 5 * 1000l;
35 private Boolean remote
= false;
37 public SpringLoginModule() {
41 @SuppressWarnings("rawtypes")
42 public void initialize(Subject subject
, CallbackHandler callbackHandler
,
43 Map sharedState
, Map options
) {
44 super.initialize(subject
, callbackHandler
, sharedState
, options
);
45 this.callbackHandler
= callbackHandler
;
46 this.subject
= subject
;
49 public boolean login() throws LoginException
{
51 // thread already logged in
52 if (SecurityContextHolder
.getContext().getAuthentication() != null)
55 // reset all principals and credentials
56 if (log
.isTraceEnabled())
57 log
.trace("Resetting all principals and credentials of "
59 if (subject
.getPrincipals() != null)
60 subject
.getPrincipals().clear();
61 if (subject
.getPrivateCredentials() != null)
62 subject
.getPrivateCredentials().clear();
63 if (subject
.getPublicCredentials() != null)
64 subject
.getPublicCredentials().clear();
66 if (callbackHandler
== null)
67 throw new LoginException("No call back handler available");
69 // ask for username and password
70 NameCallback nameCallback
= new NameCallback("User");
71 PasswordCallback passwordCallback
= new PasswordCallback(
73 final String defaultNodeUrl
= "http://localhost:7070/org.argeo.jcr.webapp/remoting/node";
74 final String defaultSecurityWorkspace
= "security";
75 NameCallback urlCallback
= new NameCallback("Site URL",
77 NameCallback securityWorkspaceCallback
= new NameCallback(
78 "Security Workspace", defaultSecurityWorkspace
);
82 callbackHandler
.handle(new Callback
[] { nameCallback
,
83 passwordCallback
, urlCallback
,
84 securityWorkspaceCallback
});
86 callbackHandler
.handle(new Callback
[] { nameCallback
,
90 String username
= nameCallback
.getName();
91 if (username
== null || username
.trim().equals(""))
95 if (passwordCallback
.getPassword() != null)
96 password
= String
.valueOf(passwordCallback
.getPassword());
98 NodeAuthenticationToken credentials
;
100 String url
= urlCallback
.getName();
101 String workspace
= securityWorkspaceCallback
.getName();
102 credentials
= new NodeAuthenticationToken(username
, password
,
105 credentials
= new NodeAuthenticationToken(username
, password
);
108 Authentication authentication
;
110 authentication
= authenticationManager
111 .authenticate(credentials
);
112 } catch (BadCredentialsException e
) {
113 // wait between failed login attempts
114 Thread
.sleep(waitBetweenFailedLoginAttempts
);
117 registerAuthentication(authentication
);
118 boolean res
= super.login();
120 } catch (LoginException e
) {
122 } catch (ThreadDeath e
) {
123 LoginException le
= new LoginException(
124 "Spring Security login thread died");
127 } catch (Exception e
) {
128 LoginException le
= new LoginException(
129 "Spring Security login failed");
136 public boolean logout() throws LoginException
{
137 subject
.getPrincipals().clear();
138 return super.logout();
142 * Register an {@link Authentication} in the security context.
144 * @param authentication
145 * has to implement {@link Authentication}.
147 protected void registerAuthentication(Object authentication
) {
148 SecurityContextHolder
.getContext().setAuthentication(
149 (Authentication
) authentication
);
152 public void setAuthenticationManager(
153 AuthenticationManager authenticationManager
) {
154 this.authenticationManager
= authenticationManager
;
157 public void setRemote(Boolean remote
) {
158 this.remote
= remote
;