1 package org
.argeo
.cms
.auth
;
3 import java
.io
.IOException
;
4 import java
.util
.Collection
;
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
;
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
;
27 public class HttpSessionLoginModule
implements LoginModule
{
28 private final static Log log
= LogFactory
.getLog(HttpSessionLoginModule
.class);
30 private Subject subject
= null;
31 private CallbackHandler callbackHandler
= null;
32 private Map
<String
, Object
> sharedState
= null;
34 private HttpServletRequest request
= null;
36 private BundleContext bc
;
38 private Authorization authorization
;
40 @SuppressWarnings("unchecked")
42 public void initialize(Subject subject
, CallbackHandler callbackHandler
, Map
<String
, ?
> sharedState
,
43 Map
<String
, ?
> options
) {
44 bc
= FrameworkUtil
.getBundle(HttpSessionLoginModule
.class).getBundleContext();
46 this.subject
= subject
;
47 this.callbackHandler
= callbackHandler
;
48 this.sharedState
= (Map
<String
, Object
>) sharedState
;
52 public boolean login() throws LoginException
{
53 if (callbackHandler
== null)
55 HttpRequestCallback httpCallback
= new HttpRequestCallback();
57 callbackHandler
.handle(new Callback
[] { httpCallback
});
58 } catch (IOException e
) {
59 throw new LoginException("Cannot handle http callback: " + e
.getMessage());
60 } catch (UnsupportedCallbackException e
) {
63 request
= httpCallback
.getRequest();
66 authorization
= (Authorization
) request
.getAttribute(HttpContext
.AUTHORIZATION
);
67 if (authorization
== null) {// search by session ID
68 String httpSessionId
= request
.getSession().getId();
69 // authorization = (Authorization)
70 // request.getSession().getAttribute(HttpContext.AUTHORIZATION);
71 // if (authorization == null) {
72 Collection
<ServiceReference
<WebCmsSession
>> sr
;
74 sr
= bc
.getServiceReferences(WebCmsSession
.class,
75 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + httpSessionId
+ ")");
76 } catch (InvalidSyntaxException e
) {
77 throw new CmsException("Cannot get CMS session for id " + httpSessionId
, e
);
80 WebCmsSession cmsSession
= bc
.getService(sr
.iterator().next());
81 authorization
= cmsSession
.getAuthorization();
82 if (log
.isTraceEnabled())
83 log
.trace("Retrieved authorization from " + cmsSession
);
84 } else if (sr
.size() == 0)
87 throw new CmsException(sr
.size() + ">1 web sessions detected for http session " + httpSessionId
);
90 if (authorization
== null)
92 sharedState
.put(CmsAuthUtils
.SHARED_STATE_AUTHORIZATION
, authorization
);
96 // private Authorization checkHttp() {
97 // Authorization authorization = null;
98 // if (request != null) {
99 // authorization = (Authorization)
100 // request.getAttribute(HttpContext.AUTHORIZATION);
101 // if (authorization == null) {
102 // String httpSessionId = request.getSession().getId();
103 // authorization = (Authorization)
104 // request.getSession().getAttribute(HttpContext.AUTHORIZATION);
105 // if (authorization == null) {
106 // Collection<ServiceReference<WebCmsSession>> sr;
108 // sr = bc.getServiceReferences(WebCmsSession.class,
109 // "(" + WebCmsSession.CMS_SESSION_ID + "=" + httpSessionId + ")");
110 // } catch (InvalidSyntaxException e) {
111 // throw new CmsException("Cannot get CMS session for id " + httpSessionId,
114 // if (sr.size() == 1) {
115 // WebCmsSession cmsSession = bc.getService(sr.iterator().next());
116 // authorization = cmsSession.getAuthorization();
117 // if (log.isTraceEnabled())
118 // log.trace("Retrieved authorization from " + cmsSession);
119 // } else if (sr.size() == 0)
122 // throw new CmsException(
123 // sr.size() + ">1 web sessions detected for http session " +
128 // return authorization;
132 public boolean commit() throws LoginException
{
133 // TODO create CmsSession in another module
134 Authorization authorizationToRegister
;
135 if (authorization
== null) {
136 authorizationToRegister
= (Authorization
) sharedState
.get(CmsAuthUtils
.SHARED_STATE_AUTHORIZATION
);
137 } else { // this login module did the authorization
138 CmsAuthUtils
.addAuthentication(subject
, authorization
);
139 authorizationToRegister
= authorization
;
141 if (authorizationToRegister
== null) {
146 HttpSessionId httpSessionId
= registerAuthorization(request
, authorizationToRegister
);
147 if (subject
.getPrivateCredentials(HttpSessionId
.class).size() == 0)
148 subject
.getPrivateCredentials().add(httpSessionId
);
150 String storedSessionId
= subject
.getPrivateCredentials(HttpSessionId
.class).iterator().next().getValue();
151 // if (storedSessionId.equals(httpSessionId.getValue()))
152 throw new LoginException(
153 "Subject already logged with session " + storedSessionId
+ " (not " + httpSessionId
+ ")");
156 if (authorization
!= null) {
157 // CmsAuthUtils.addAuthentication(subject, authorization);
166 private HttpSessionId
registerAuthorization(HttpServletRequest request
, Authorization authorization
) {
167 String httpSessionId
= request
.getSession().getId();
168 if (authorization
.getName() != null) {
169 request
.setAttribute(HttpContext
.REMOTE_USER
, authorization
.getName());
170 request
.setAttribute(HttpContext
.AUTHORIZATION
, authorization
);
172 HttpSession httpSession
= request
.getSession();
173 if (httpSession
.getAttribute(HttpContext
.AUTHORIZATION
) == null) {
175 Collection
<ServiceReference
<WebCmsSession
>> sr
;
177 sr
= bc
.getServiceReferences(WebCmsSession
.class,
178 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + httpSessionId
+ ")");
179 } catch (InvalidSyntaxException e
) {
180 throw new CmsException("Cannot get CMS session for id " + httpSessionId
, e
);
182 ServiceReference
<WebCmsSession
> cmsSessionRef
;
183 if (sr
.size() == 1) {
184 cmsSessionRef
= sr
.iterator().next();
185 } else if (sr
.size() == 0) {
186 WebCmsSessionImpl cmsSessionImpl
= new WebCmsSessionImpl(httpSessionId
, authorization
);
187 cmsSessionRef
= cmsSessionImpl
.getServiceRegistration().getReference();
188 if (log
.isDebugEnabled())
189 log
.debug("Initialized " + cmsSessionImpl
+ " for " + authorization
.getName());
191 throw new CmsException(sr
.size() + " CMS sessions registered for " + httpSessionId
);
193 WebCmsSessionImpl cmsSession
= (WebCmsSessionImpl
) bc
.getService(cmsSessionRef
);
194 cmsSession
.addHttpSession(request
);
195 if (log
.isTraceEnabled())
196 log
.trace("Added " + request
.getServletPath() + " to " + cmsSession
+ " (" + request
.getRequestURI()
198 // httpSession.setAttribute(HttpContext.REMOTE_USER,
199 // authorization.getName());
200 // httpSession.setAttribute(HttpContext.AUTHORIZATION,
204 return new HttpSessionId(httpSessionId
);
208 public boolean abort() throws LoginException
{
213 private void cleanUp() {
214 authorization
= null;
219 public boolean logout() throws LoginException
{
220 String httpSessionId
;
221 if (subject
.getPrivateCredentials(HttpSessionId
.class).size() == 1)
222 httpSessionId
= subject
.getPrivateCredentials(HttpSessionId
.class).iterator().next().getValue();
225 Collection
<ServiceReference
<WebCmsSession
>> srs
;
227 srs
= bc
.getServiceReferences(WebCmsSession
.class,
228 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + httpSessionId
+ ")");
229 } catch (InvalidSyntaxException e
) {
230 throw new CmsException("Cannot retrieve CMS session #" + httpSessionId
, e
);
234 throw new CmsException("No CMS web session found for http session " + httpSessionId
);
235 else if (srs
.size() > 1)
236 throw new CmsException(srs
.size() + " CMS web sessions found for http session " + httpSessionId
);
238 WebCmsSessionImpl cmsSession
= (WebCmsSessionImpl
) bc
.getService(srs
.iterator().next());
239 cmsSession
.cleanUp();
240 subject
.getPrivateCredentials().removeAll(subject
.getPrivateCredentials(HttpSessionId
.class));
241 if (log
.isDebugEnabled())
242 log
.debug("Cleaned up " + cmsSession
);