]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/HttpLoginModule.java
Remove deprecated APIs
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / HttpLoginModule.java
1 package org.argeo.cms.auth;
2
3 import java.io.IOException;
4 import java.util.Collection;
5 import java.util.Map;
6
7 import javax.security.auth.Subject;
8 import javax.security.auth.callback.Callback;
9 import javax.security.auth.callback.CallbackHandler;
10 import javax.security.auth.callback.UnsupportedCallbackException;
11 import javax.security.auth.login.LoginException;
12 import javax.security.auth.spi.LoginModule;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpSession;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.argeo.cms.CmsException;
19 import org.argeo.cms.internal.kernel.WebCmsSessionImpl;
20 import org.osgi.framework.BundleContext;
21 import org.osgi.framework.FrameworkUtil;
22 import org.osgi.framework.InvalidSyntaxException;
23 import org.osgi.framework.ServiceReference;
24 import org.osgi.service.http.HttpContext;
25 import org.osgi.service.useradmin.Authorization;
26
27 public class HttpLoginModule implements LoginModule, AuthConstants {
28 private final static Log log = LogFactory.getLog(HttpLoginModule.class);
29
30 private Subject subject = null;
31 private CallbackHandler callbackHandler = null;
32 private Map<String, Object> sharedState = null;
33
34 private HttpServletRequest request = null;
35
36 private BundleContext bc;
37
38 @SuppressWarnings("unchecked")
39 @Override
40 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
41 Map<String, ?> options) {
42 bc = FrameworkUtil.getBundle(HttpLoginModule.class).getBundleContext();
43 assert bc != null;
44 this.subject = subject;
45 this.callbackHandler = callbackHandler;
46 this.sharedState = (Map<String, Object>) sharedState;
47 }
48
49 @Override
50 public boolean login() throws LoginException {
51 HttpRequestCallback httpCallback = new HttpRequestCallback();
52 try {
53 callbackHandler.handle(new Callback[] { httpCallback });
54 } catch (IOException e) {
55 throw new LoginException("Cannot handle http callback: " + e.getMessage());
56 } catch (UnsupportedCallbackException e) {
57 return false;
58 }
59 request = httpCallback.getRequest();
60 if (request == null)
61 return false;
62 Authorization authorization = checkHttp();
63 if (authorization == null)
64 return false;
65 sharedState.put(SHARED_STATE_AUTHORIZATION, authorization);
66 return true;
67 }
68
69 private Authorization checkHttp() {
70 Authorization authorization = null;
71 if (request != null) {
72 authorization = (Authorization) request.getAttribute(HttpContext.AUTHORIZATION);
73 if (authorization == null) {
74 String httpSessionId = request.getSession().getId();
75 authorization = (Authorization) request.getSession().getAttribute(HttpContext.AUTHORIZATION);
76 if (authorization == null) {
77 Collection<ServiceReference<WebCmsSession>> sr;
78 try {
79 sr = bc.getServiceReferences(WebCmsSession.class,
80 "(" + WebCmsSession.CMS_SESSION_ID + "=" + httpSessionId + ")");
81 } catch (InvalidSyntaxException e) {
82 throw new CmsException("Cannot get CMS session for id " + httpSessionId, e);
83 }
84 if (sr.size() == 1) {
85 WebCmsSession cmsSession = bc.getService(sr.iterator().next());
86 authorization = cmsSession.getAuthorization();
87 if (log.isTraceEnabled())
88 log.trace("Retrieved authorization from " + cmsSession);
89 } else if (sr.size() == 0)
90 return null;
91 else
92 throw new CmsException(
93 sr.size() + ">1 web sessions detected for http session " + httpSessionId);
94 }
95 }
96 }
97 return authorization;
98 }
99
100 @Override
101 public boolean commit() throws LoginException {
102 Authorization authorization = (Authorization) sharedState.get(SHARED_STATE_AUTHORIZATION);
103 if (authorization == null)
104 return false;
105 if (request == null)
106 return false;
107 String httpSessionId = request.getSession().getId();
108 if (authorization.getName() != null) {
109 request.setAttribute(HttpContext.REMOTE_USER, authorization.getName());
110 request.setAttribute(HttpContext.AUTHORIZATION, authorization);
111
112 HttpSession httpSession = request.getSession();
113 if (httpSession.getAttribute(HttpContext.AUTHORIZATION) == null) {
114
115 Collection<ServiceReference<WebCmsSession>> sr;
116 try {
117 sr = bc.getServiceReferences(WebCmsSession.class,
118 "(" + WebCmsSession.CMS_SESSION_ID + "=" + httpSessionId + ")");
119 } catch (InvalidSyntaxException e) {
120 throw new CmsException("Cannot get CMS session for id " + httpSessionId, e);
121 }
122 ServiceReference<WebCmsSession> cmsSessionRef;
123 if (sr.size() == 1) {
124 cmsSessionRef = sr.iterator().next();
125 } else if (sr.size() == 0) {
126 WebCmsSessionImpl cmsSessionImpl = new WebCmsSessionImpl(httpSessionId, authorization);
127 cmsSessionRef = cmsSessionImpl.getServiceRegistration().getReference();
128 if (log.isDebugEnabled())
129 log.debug("Initialized " + cmsSessionImpl + " for " + authorization.getName());
130 } else
131 throw new CmsException(sr.size() + " CMS sessions registered for " + httpSessionId);
132
133 WebCmsSessionImpl cmsSession = (WebCmsSessionImpl) bc.getService(cmsSessionRef);
134 cmsSession.addHttpSession(request);
135 if (log.isTraceEnabled())
136 log.trace("Added " + request.getServletPath() + " to " + cmsSession + " (" + request.getRequestURI()
137 + ")");
138 httpSession.setAttribute(HttpContext.AUTHORIZATION, authorization);
139 }
140 }
141 if (subject.getPrivateCredentials(HttpSessionId.class).size() == 0)
142 subject.getPrivateCredentials().add(new HttpSessionId(httpSessionId));
143 else {
144 String storedSessionId = subject.getPrivateCredentials(HttpSessionId.class).iterator().next().getValue();
145 if (storedSessionId.equals(httpSessionId))
146 throw new LoginException(
147 "Subject already logged with session " + storedSessionId + " (not " + httpSessionId + ")");
148 }
149 return true;
150 }
151
152 @Override
153 public boolean abort() throws LoginException {
154 return false;
155 }
156
157 @Override
158 public boolean logout() throws LoginException {
159 String httpSessionId;
160 if (subject.getPrivateCredentials(HttpSessionId.class).size() == 1)
161 httpSessionId = subject.getPrivateCredentials(HttpSessionId.class).iterator().next().getValue();
162 else
163 return false;
164 Collection<ServiceReference<WebCmsSession>> srs;
165 try {
166 srs = bc.getServiceReferences(WebCmsSession.class,
167 "(" + WebCmsSession.CMS_SESSION_ID + "=" + httpSessionId + ")");
168 } catch (InvalidSyntaxException e) {
169 throw new CmsException("Cannot retrieve CMS session #" + httpSessionId, e);
170 }
171
172 if (srs.size() == 0)
173 throw new CmsException("No CMS web sesison found for http session " + httpSessionId);
174 else if (srs.size() > 1)
175 throw new CmsException(srs.size() + " CMS web sessions found for http session " + httpSessionId);
176
177 WebCmsSessionImpl cmsSession = (WebCmsSessionImpl) bc.getService(srs.iterator().next());
178 cmsSession.cleanUp();
179 subject.getPrivateCredentials().removeAll(subject.getPrivateCredentials(HttpSessionId.class));
180 if (log.isDebugEnabled())
181 log.debug("Cleaned up " + cmsSession);
182 return true;
183 }
184
185 }