1 package org
.argeo
.cms
.servlet
;
3 import java
.io
.IOException
;
5 import java
.security
.PrivilegedAction
;
8 import javax
.security
.auth
.Subject
;
9 import javax
.security
.auth
.login
.LoginContext
;
10 import javax
.security
.auth
.login
.LoginException
;
11 import javax
.servlet
.http
.HttpServletRequest
;
12 import javax
.servlet
.http
.HttpServletResponse
;
14 import org
.argeo
.api
.cms
.CmsAuth
;
15 import org
.argeo
.api
.cms
.CmsLog
;
16 import org
.argeo
.cms
.auth
.RemoteAuthCallbackHandler
;
17 import org
.argeo
.cms
.auth
.RemoteAuthRequest
;
18 import org
.argeo
.cms
.auth
.RemoteAuthResponse
;
19 import org
.argeo
.cms
.auth
.RemoteAuthUtils
;
20 import org
.argeo
.cms
.servlet
.internal
.HttpUtils
;
21 import org
.osgi
.framework
.Bundle
;
22 import org
.osgi
.framework
.FrameworkUtil
;
23 import org
.osgi
.service
.http
.context
.ServletContextHelper
;
26 * Default servlet context degrading to anonymous if the the session is not
29 public class CmsServletContext
extends ServletContextHelper
{
30 private final static CmsLog log
= CmsLog
.getLog(CmsServletContext
.class);
31 // use CMS bundle for resources
32 private Bundle bundle
= FrameworkUtil
.getBundle(getClass());
34 private final String httpAuthRealm
= "Argeo";
35 private final boolean forceBasic
= false;
37 public void init(Map
<String
, String
> properties
) {
41 public void destroy() {
46 public boolean handleSecurity(HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
47 if (log
.isTraceEnabled())
48 HttpUtils
.logRequestHeaders(log
, request
);
49 RemoteAuthRequest remoteAuthRequest
= new ServletHttpRequest(request
);
50 RemoteAuthResponse remoteAuthResponse
= new ServletHttpResponse(response
);
51 ClassLoader currentThreadContextClassLoader
= Thread
.currentThread().getContextClassLoader();
52 Thread
.currentThread().setContextClassLoader(CmsServletContext
.class.getClassLoader());
55 lc
= CmsAuth
.USER
.newLoginContext(new RemoteAuthCallbackHandler(remoteAuthRequest
, remoteAuthResponse
));
57 } catch (LoginException e
) {
58 // FIXME better analyse failure so as not to try endlessly
59 if (authIsRequired(remoteAuthRequest
, remoteAuthResponse
)) {
60 int statusCode
= RemoteAuthUtils
.askForWwwAuth(remoteAuthResponse
, httpAuthRealm
, forceBasic
);
61 response
.setStatus(statusCode
);
65 lc
= RemoteAuthUtils
.anonymousLogin(remoteAuthRequest
, remoteAuthResponse
);
70 Thread
.currentThread().setContextClassLoader(currentThreadContextClassLoader
);
73 Subject subject
= lc
.getSubject();
74 Subject
.doAs(subject
, new PrivilegedAction
<Void
>() {
78 // TODO also set login context in order to log out ?
79 RemoteAuthUtils
.configureRequestSecurity(remoteAuthRequest
);
88 public void finishSecurity(HttpServletRequest request
, HttpServletResponse response
) {
89 RemoteAuthUtils
.clearRequestSecurity(new ServletHttpRequest(request
));
92 protected boolean authIsRequired(RemoteAuthRequest remoteAuthRequest
, RemoteAuthResponse remoteAuthResponse
) {
96 // protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
98 // ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
100 // Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader());
101 // LoginContext lc = CmsAuth.ANONYMOUS.newLoginContext(
102 // new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response)));
105 // } catch (LoginException e1) {
106 // if (log.isDebugEnabled())
107 // log.error("Cannot log in as anonymous", e1);
110 // Thread.currentThread().setContextClassLoader(currentContextClassLoader);
115 public URL
getResource(String name
) {
116 // TODO make it more robust and versatile
117 // if used directly it can only load from within this bundle
118 return bundle
.getResource(name
);