X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.cms.ee%2Fsrc%2Forg%2Fargeo%2Fcms%2Fservlet%2FCmsServletContext.java;fp=org.argeo.cms.ee%2Fsrc%2Forg%2Fargeo%2Fcms%2Fservlet%2FCmsServletContext.java;h=9cb48b212d38b5db6054c6fefac76dc00a9a00e3;hb=00753f77ac3f41f7dbfe281eeab886ef4bdc0ce5;hp=0000000000000000000000000000000000000000;hpb=fa0040a5e9655896bb32c4db7392cf1f08f8be63;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms.ee/src/org/argeo/cms/servlet/CmsServletContext.java b/org.argeo.cms.ee/src/org/argeo/cms/servlet/CmsServletContext.java new file mode 100644 index 000000000..9cb48b212 --- /dev/null +++ b/org.argeo.cms.ee/src/org/argeo/cms/servlet/CmsServletContext.java @@ -0,0 +1,106 @@ +package org.argeo.cms.servlet; + +import java.io.IOException; +import java.net.URL; +import java.security.PrivilegedAction; +import java.util.Map; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsLog; +import org.argeo.cms.auth.RemoteAuthCallbackHandler; +import org.argeo.cms.auth.RemoteAuthUtils; +import org.argeo.cms.servlet.internal.HttpUtils; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.osgi.service.http.context.ServletContextHelper; + +/** + * Default servlet context degrading to anonymous if the the session is not + * pre-authenticated. + */ +public class CmsServletContext extends ServletContextHelper { + private final static CmsLog log = CmsLog.getLog(CmsServletContext.class); + // use CMS bundle for resources + private Bundle bundle = FrameworkUtil.getBundle(getClass()); + + public void init(Map properties) { + + } + + public void destroy() { + + } + + @Override + public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { + if (log.isTraceEnabled()) + HttpUtils.logRequestHeaders(log, request); + ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader()); + LoginContext lc; + try { + lc = CmsAuth.USER.newLoginContext( + new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response))); + lc.login(); + } catch (LoginException e) { + lc = processUnauthorized(request, response); + if (log.isTraceEnabled()) + HttpUtils.logResponseHeaders(log, response); + if (lc == null) + return false; + } finally { + Thread.currentThread().setContextClassLoader(currentThreadContextClassLoader); + } + + Subject subject = lc.getSubject(); + // log.debug("SERVLET CONTEXT: "+subject); + Subject.doAs(subject, new PrivilegedAction() { + + @Override + public Void run() { + // TODO also set login context in order to log out ? + RemoteAuthUtils.configureRequestSecurity(new ServletHttpRequest(request)); + return null; + } + + }); + return true; + } + + @Override + public void finishSecurity(HttpServletRequest request, HttpServletResponse response) { + RemoteAuthUtils.clearRequestSecurity(new ServletHttpRequest(request)); + } + + protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) { + // anonymous + ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader()); + LoginContext lc = CmsAuth.ANONYMOUS.newLoginContext( + new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response))); + lc.login(); + return lc; + } catch (LoginException e1) { + if (log.isDebugEnabled()) + log.error("Cannot log in as anonymous", e1); + return null; + } finally { + Thread.currentThread().setContextClassLoader(currentContextClassLoader); + } + } + + @Override + public URL getResource(String name) { + // TODO make it more robust and versatile + // if used directly it can only load from within this bundle + return bundle.getResource(name); + } + +}