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 HttpLoginModule
implements LoginModule
, AuthConstants
{
28 private final static Log log
= LogFactory
.getLog(HttpLoginModule
.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 @SuppressWarnings("unchecked")
40 public void initialize(Subject subject
, CallbackHandler callbackHandler
, Map
<String
, ?
> sharedState
,
41 Map
<String
, ?
> options
) {
42 bc
= FrameworkUtil
.getBundle(HttpLoginModule
.class).getBundleContext();
44 this.subject
= subject
;
45 this.callbackHandler
= callbackHandler
;
46 this.sharedState
= (Map
<String
, Object
>) sharedState
;
50 public boolean login() throws LoginException
{
51 HttpRequestCallback httpCallback
= new HttpRequestCallback();
53 callbackHandler
.handle(new Callback
[] { httpCallback
});
54 } catch (IOException e
) {
55 throw new LoginException("Cannot handle http callback: " + e
.getMessage());
56 } catch (UnsupportedCallbackException e
) {
59 request
= httpCallback
.getRequest();
62 Authorization authorization
= checkHttp();
63 if (authorization
== null)
65 sharedState
.put(SHARED_STATE_AUTHORIZATION
, authorization
);
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
;
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
);
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)
92 throw new CmsException(
93 sr
.size() + ">1 web sessions detected for http session " + httpSessionId
);
101 public boolean commit() throws LoginException
{
102 Authorization authorization
= (Authorization
) sharedState
.get(SHARED_STATE_AUTHORIZATION
);
103 if (authorization
== null)
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
);
112 HttpSession httpSession
= request
.getSession();
113 if (httpSession
.getAttribute(HttpContext
.AUTHORIZATION
) == null) {
115 Collection
<ServiceReference
<WebCmsSession
>> sr
;
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
);
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());
131 throw new CmsException(sr
.size() + " CMS sessions registered for " + httpSessionId
);
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()
138 httpSession
.setAttribute(HttpContext
.AUTHORIZATION
, authorization
);
141 if (subject
.getPrivateCredentials(HttpSessionId
.class).size() == 0)
142 subject
.getPrivateCredentials().add(new HttpSessionId(httpSessionId
));
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
+ ")");
153 public boolean abort() throws LoginException
{
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();
164 Collection
<ServiceReference
<WebCmsSession
>> srs
;
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
);
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
);
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
);