1 package org
.argeo
.cms
.auth
;
3 import java
.io
.IOException
;
4 import java
.util
.Collection
;
5 import java
.util
.Hashtable
;
6 import java
.util
.Iterator
;
9 import javax
.security
.auth
.Subject
;
10 import javax
.security
.auth
.callback
.Callback
;
11 import javax
.security
.auth
.callback
.CallbackHandler
;
12 import javax
.security
.auth
.callback
.UnsupportedCallbackException
;
13 import javax
.security
.auth
.login
.LoginException
;
14 import javax
.security
.auth
.spi
.LoginModule
;
15 import javax
.servlet
.http
.HttpServletRequest
;
16 import javax
.servlet
.http
.HttpSession
;
18 import org
.apache
.commons
.logging
.Log
;
19 import org
.apache
.commons
.logging
.LogFactory
;
20 import org
.argeo
.cms
.CmsException
;
21 import org
.argeo
.cms
.internal
.kernel
.WebCmsSessionImpl
;
22 import org
.osgi
.framework
.BundleContext
;
23 import org
.osgi
.framework
.FrameworkUtil
;
24 import org
.osgi
.framework
.InvalidSyntaxException
;
25 import org
.osgi
.framework
.ServiceReference
;
26 import org
.osgi
.framework
.ServiceRegistration
;
27 import org
.osgi
.service
.http
.HttpContext
;
28 import org
.osgi
.service
.useradmin
.Authorization
;
30 public class HttpLoginModule
implements LoginModule
, AuthConstants
{
31 private final static Log log
= LogFactory
.getLog(HttpLoginModule
.class);
33 private Subject subject
= null;
34 private CallbackHandler callbackHandler
= null;
35 private Map
<String
, Object
> sharedState
= null;
37 private HttpServletRequest request
= null;
39 private BundleContext bc
;
41 @SuppressWarnings("unchecked")
43 public void initialize(Subject subject
, CallbackHandler callbackHandler
, Map
<String
, ?
> sharedState
,
44 Map
<String
, ?
> options
) {
45 bc
= FrameworkUtil
.getBundle(HttpLoginModule
.class).getBundleContext();
47 this.subject
= subject
;
48 this.callbackHandler
= callbackHandler
;
49 this.sharedState
= (Map
<String
, Object
>) sharedState
;
53 public boolean login() throws LoginException
{
54 HttpRequestCallback httpCallback
= new HttpRequestCallback();
56 callbackHandler
.handle(new Callback
[] { httpCallback
});
57 } catch (IOException e
) {
58 throw new LoginException("Cannot handle http callback: " + e
.getMessage());
59 } catch (UnsupportedCallbackException e
) {
62 request
= httpCallback
.getRequest();
65 Authorization authorization
= checkHttp();
66 if (authorization
== null)
68 sharedState
.put(SHARED_STATE_AUTHORIZATION
, authorization
);
72 private Authorization
checkHttp() {
73 Authorization authorization
= null;
74 if (request
!= null) {
75 authorization
= (Authorization
) request
.getAttribute(HttpContext
.AUTHORIZATION
);
76 if (authorization
== null) {
77 String sessionId
= request
.getSession().getId();
78 authorization
= (Authorization
) request
.getSession().getAttribute(HttpContext
.AUTHORIZATION
);
79 if (authorization
== null) {
80 Collection
<ServiceReference
<WebCmsSession
>> sr
;
82 sr
= bc
.getServiceReferences(WebCmsSession
.class,
83 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + sessionId
+ ")");
84 } catch (InvalidSyntaxException e
) {
85 throw new CmsException("Cannot get CMS session for id " + sessionId
, e
);
88 WebCmsSession cmsSession
= bc
.getService(sr
.iterator().next());
89 authorization
= cmsSession
.getAuthorization();
90 if (log
.isTraceEnabled())
91 log
.trace("Retrieved authorization from " + cmsSession
);
100 public boolean commit() throws LoginException
{
101 Authorization authorization
= (Authorization
) sharedState
.get(SHARED_STATE_AUTHORIZATION
);
102 if (authorization
== null)
106 String sessionId
= request
.getSession().getId();
107 if (authorization
.getName() != null) {
108 request
.setAttribute(HttpContext
.REMOTE_USER
, authorization
.getName());
109 request
.setAttribute(HttpContext
.AUTHORIZATION
, authorization
);
111 HttpSession httpSession
= request
.getSession();
112 if (httpSession
.getAttribute(HttpContext
.AUTHORIZATION
) == null) {
114 Collection
<ServiceReference
<WebCmsSession
>> sr
;
116 sr
= bc
.getServiceReferences(WebCmsSession
.class,
117 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + sessionId
+ ")");
118 } catch (InvalidSyntaxException e
) {
119 throw new CmsException("Cannot get CMS session for id " + sessionId
, e
);
121 ServiceReference
<WebCmsSession
> cmsSessionRef
;
122 if (sr
.size() == 1) {
123 cmsSessionRef
= sr
.iterator().next();
124 } else if (sr
.size() == 0) {
125 Hashtable
<String
, String
> props
= new Hashtable
<>();
126 props
.put(WebCmsSession
.CMS_DN
, authorization
.getName());
127 props
.put(WebCmsSession
.CMS_SESSION_ID
, sessionId
);
128 WebCmsSessionImpl cmsSessionImpl
= new WebCmsSessionImpl(sessionId
, authorization
);
129 ServiceRegistration
<WebCmsSession
> cmSessionReg
= bc
.registerService(WebCmsSession
.class,
130 cmsSessionImpl
, props
);
131 cmsSessionImpl
.setServiceRegistration(cmSessionReg
);
132 cmsSessionRef
= cmSessionReg
.getReference();
133 if (log
.isDebugEnabled())
134 log
.debug("Initialized " + cmsSessionImpl
+ " for " + authorization
.getName());
136 throw new CmsException(sr
.size() + " CMS sessions registered for " + sessionId
);
138 WebCmsSession cmsSession
= bc
.getService(cmsSessionRef
);
139 cmsSession
.addHttpSession(request
);
140 if (log
.isTraceEnabled())
141 log
.trace("Added " + request
.getServletPath() + " to " + cmsSession
+ " (" + request
.getRequestURI()
143 httpSession
.setAttribute(HttpContext
.AUTHORIZATION
, authorization
);
146 if (subject
.getPrivateCredentials(HttpSessionId
.class).size() == 0)
147 subject
.getPrivateCredentials().add(new HttpSessionId(sessionId
));
149 String storedSessionId
= subject
.getPrivateCredentials(HttpSessionId
.class).iterator().next().getValue();
150 if (storedSessionId
.equals(sessionId
))
151 throw new LoginException(
152 "Subject already logged with session " + storedSessionId
+ " (not " + sessionId
+ ")");
158 public boolean abort() throws LoginException
{
163 public boolean logout() throws LoginException
{
165 if (subject
.getPrivateCredentials(HttpSessionId
.class).size() == 1)
166 sessionId
= subject
.getPrivateCredentials(HttpSessionId
.class).iterator().next().getValue();
169 Collection
<ServiceReference
<WebCmsSession
>> srs
;
171 srs
= bc
.getServiceReferences(WebCmsSession
.class,
172 "(" + WebCmsSession
.CMS_SESSION_ID
+ "=" + sessionId
+ ")");
173 } catch (InvalidSyntaxException e
) {
174 throw new CmsException("Cannot retrieve CMS session #" + sessionId
, e
);
177 for (Iterator
<ServiceReference
<WebCmsSession
>> it
= srs
.iterator(); it
.hasNext();) {
178 ServiceReference
<WebCmsSession
> sr
= it
.next();
179 WebCmsSession cmsSession
= bc
.getService(sr
);
180 cmsSession
.cleanUp();
181 if (log
.isDebugEnabled())
182 log
.debug("Cleaned up " + cmsSession
);