]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java
Fix issues with multi session
[lgpl/argeo-commons.git] / security / plugins / org.argeo.security.equinox / src / main / java / org / argeo / security / equinox / SpringLoginModule.java
1 package org.argeo.security.equinox;
2
3 import java.util.Map;
4
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.callback.TextOutputCallback;
11 import javax.security.auth.login.LoginException;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.security.SiteAuthenticationToken;
16 import org.springframework.security.Authentication;
17 import org.springframework.security.AuthenticationManager;
18 import org.springframework.security.BadCredentialsException;
19 import org.springframework.security.context.SecurityContextHolder;
20 import org.springframework.security.providers.jaas.SecurityContextLoginModule;
21
22 /** Login module which caches one subject per thread. */
23 public class SpringLoginModule extends SecurityContextLoginModule {
24 private final static Log log = LogFactory.getLog(SpringLoginModule.class);
25
26 private AuthenticationManager authenticationManager;
27
28 private CallbackHandler callbackHandler;
29
30 private Subject subject;
31
32 public SpringLoginModule() {
33
34 }
35
36 @SuppressWarnings("rawtypes")
37 public void initialize(Subject subject, CallbackHandler callbackHandler,
38 Map sharedState, Map options) {
39 super.initialize(subject, callbackHandler, sharedState, options);
40 this.callbackHandler = callbackHandler;
41 this.subject = subject;
42 }
43
44 public boolean login() throws LoginException {
45 // try to retrieve Authentication from Subject
46 // Set<Authentication> auths =
47 // subject.getPrincipals(Authentication.class);
48 // if (auths.size() > 0)
49 // SecurityContextHolder.getContext().setAuthentication(
50 // auths.iterator().next());
51
52 // thread already logged in
53 if (SecurityContextHolder.getContext().getAuthentication() != null)
54 return super.login();
55
56 // reset all principals and credentials
57 if (log.isTraceEnabled())
58 log.trace("Resetting all principals and credentials of " + subject);
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();
65
66 // ask for username and password
67 Callback label = new TextOutputCallback(TextOutputCallback.INFORMATION,
68 "Required login");
69 NameCallback nameCallback = new NameCallback("User");
70 PasswordCallback passwordCallback = new PasswordCallback("Password",
71 false);
72
73 // NameCallback urlCallback = new NameCallback("Site URL");
74
75 if (callbackHandler == null) {
76 throw new LoginException("No call back handler available");
77 // return false;
78 }
79 try {
80 callbackHandler.handle(new Callback[] { label, nameCallback,
81 passwordCallback });
82 } catch (Exception e) {
83 throw new RuntimeException("Unexpected exception when handling", e);
84 }
85
86 // Set user name and password
87 String username = nameCallback.getName();
88 String password = "";
89 if (passwordCallback.getPassword() != null) {
90 password = String.valueOf(passwordCallback.getPassword());
91 }
92
93 // String url = urlCallback.getName();
94 // TODO: set it via system properties
95 String workspace = null;
96
97 SiteAuthenticationToken credentials = new SiteAuthenticationToken(
98 username, password, null, workspace);
99
100 try {
101 Authentication authentication = authenticationManager
102 .authenticate(credentials);
103 registerAuthentication(authentication);
104 boolean res = super.login();
105 return res;
106 } catch (BadCredentialsException bce) {
107 throw bce;
108 } catch (Exception e) {
109 LoginException loginException = new LoginException(
110 "Bad credentials");
111 loginException.initCause(e);
112 throw loginException;
113 }
114 }
115
116 @Override
117 public boolean logout() throws LoginException {
118 subject.getPrincipals().clear();
119 return super.logout();
120 }
121
122 /**
123 * Register an {@link Authentication} in the security context.
124 *
125 * @param authentication
126 * has to implement {@link Authentication}.
127 */
128 protected void registerAuthentication(Object authentication) {
129 SecurityContextHolder.getContext().setAuthentication(
130 (Authentication) authentication);
131 }
132
133 public void setAuthenticationManager(
134 AuthenticationManager authenticationManager) {
135 this.authenticationManager = authenticationManager;
136 }
137 }