]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
Improve login mechanism, based on JAAS
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / NodeHttp.java
index db66de2eaa989e75a8bf809635c1c29a4a89e0fc..f0fbe461a1dfc8ecc5d5c5be3862c60587d48983 100644 (file)
@@ -1,12 +1,14 @@
 package org.argeo.cms.internal.kernel;
 
 import java.io.IOException;
+import java.util.Enumeration;
 import java.util.Properties;
 import java.util.StringTokenizer;
 
 import javax.servlet.FilterChain;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -20,6 +22,7 @@ import org.argeo.jackrabbit.servlet.RemotingServlet;
 import org.argeo.jackrabbit.servlet.WebdavServlet;
 import org.argeo.jcr.ArgeoJcrConstants;
 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
+import org.eclipse.jetty.servlets.DoSFilter;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.http.NamespaceException;
 import org.osgi.util.tracker.ServiceTracker;
@@ -40,8 +43,6 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        private final static String HEADER_AUTHORIZATION = "Authorization";
        private final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
 
-       static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
-
        private final AuthenticationManager authenticationManager;
        private final BundleContext bundleContext;
        private ExtendedHttpService httpService;
@@ -50,7 +51,9 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        private String httpAuthRealm = "Argeo";
 
        // Filters
-       // private final RootFilter rootFilter;
+       private final RootFilter rootFilter;
+       // private final DoSFilter dosFilter;
+       // private final QoSFilter qosFilter;
 
        // remoting
        private OpenInViewSessionProvider sessionProvider;
@@ -79,7 +82,9 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                        + ExtendedHttpService.class + " service.");
 
                // Filters
-               // rootFilter = new RootFilter();
+               rootFilter = new RootFilter();
+               // dosFilter = new CustomDosFilter();
+               // qosFilter = new QoSFilter();
 
                // DAV
                sessionProvider = new OpenInViewSessionProvider();
@@ -100,7 +105,9 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                        registerRemotingServlet(PATH_REMOTING_PRIVATE, ALIAS_NODE, false,
                                        privateRemotingServlet);
 
-                       // httpService.registerFilter("/", rootFilter, null, null);
+                       // httpService.registerFilter("/", dosFilter, null, null);
+                       httpService.registerFilter("/", rootFilter, null, null);
+                       // httpService.registerFilter("/", qosFilter, null, null);
                } catch (Exception e) {
                        throw new CmsException("Cannot publish HTTP services to OSGi", e);
                }
@@ -166,7 +173,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                        try {
                                                String credentials = new String(Base64.decodeBase64(st
                                                                .nextToken()), "UTF-8");
-                                               log.debug("Credentials: " + credentials);
+                                               // log.debug("Credentials: " + credentials);
                                                int p = credentials.indexOf(":");
                                                if (p != -1) {
                                                        String login = credentials.substring(0, p).trim();
@@ -174,7 +181,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                                                        .trim();
 
                                                        return new UsernamePasswordAuthenticationToken(
-                                                                       login, password);
+                                                                       login, password.toCharArray());
                                                } else {
                                                        throw new CmsException(
                                                                        "Invalid authentication token");
@@ -196,41 +203,45 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                public void doFilter(HttpSession httpSession,
                                HttpServletRequest request, HttpServletResponse response,
                                FilterChain filterChain) throws IOException, ServletException {
-
-                       // Authenticate from session
-                       if (isSessionAuthenticated(httpSession)) {
-                               filterChain.doFilter(request, response);
-                               return;
+                       if (log.isTraceEnabled()) {
+                               log.debug(request.getContextPath());
+                               log.debug(request.getServletPath());
+                               log.debug(request.getRequestURI());
+                               log.debug(request.getQueryString());
+                               StringBuilder buf = new StringBuilder();
+                               Enumeration<String> en = request.getHeaderNames();
+                               while (en.hasMoreElements()) {
+                                       String header = en.nextElement();
+                                       Enumeration<String> values = request.getHeaders(header);
+                                       while (values.hasMoreElements())
+                                               buf.append("  " + header + ": " + values.nextElement());
+                                       buf.append('\n');
+                               }
+                               log.debug("\n" + buf);
                        }
 
-                       // TODO Kerberos
-
-                       // TODO Certificate
+                       String servletPath = request.getServletPath();
 
-                       // Process basic auth
-                       String basicAuth = request.getHeader(HEADER_AUTHORIZATION);
-                       if (basicAuth != null) {
-                               UsernamePasswordAuthenticationToken token = basicAuth(basicAuth);
-                               Authentication auth = authenticationManager.authenticate(token);
-                               SecurityContextHolder.getContext().setAuthentication(auth);
-                               httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
-                                               SecurityContextHolder.getContext());
-                               httpSession.setAttribute(ATTR_AUTH, Boolean.FALSE);
+                       // skip data
+                       if (servletPath.startsWith(PATH_DATA)) {
                                filterChain.doFilter(request, response);
                                return;
                        }
 
-                       Boolean doBasicAuth = true;
-                       if (doBasicAuth) {
-                               requestBasicAuth(httpSession, response);
-                               // skip filter chain
+                       // redirect long RWT paths to anchor
+                       String path = request.getRequestURI().substring(
+                                       servletPath.length());
+                       int pathLength = path.length();
+                       if (pathLength != 0 && (path.charAt(0) == '/')
+                                       && !servletPath.endsWith("rwt-resources")
+                                       && !path.equals("/")) {
+                               String newLocation = request.getServletPath() + "#" + path;
+                               response.setHeader("Location", newLocation);
+                               response.setStatus(HttpServletResponse.SC_FOUND);
                                return;
                        }
 
-                       // TODO Login page
-
-                       // Anonymous
-                       KernelUtils.anonymousLogin(authenticationManager);
+                       // process normally
                        filterChain.doFilter(request, response);
                }
        }
@@ -262,10 +273,10 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                FilterChain filterChain) throws IOException, ServletException {
 
                        // Authenticate from session
-                       if (isSessionAuthenticated(httpSession)) {
-                               filterChain.doFilter(request, response);
-                               return;
-                       }
+                       // if (isSessionAuthenticated(httpSession)) {
+                       // filterChain.doFilter(request, response);
+                       // return;
+                       // }
 
                        // Process basic auth
                        String basicAuth = request.getHeader(HEADER_AUTHORIZATION);
@@ -284,4 +295,19 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                }
        }
 
+       class CustomDosFilter extends DoSFilter {
+               @Override
+               protected String extractUserId(ServletRequest request) {
+                       HttpSession httpSession = ((HttpServletRequest) request)
+                                       .getSession();
+                       if (isSessionAuthenticated(httpSession)) {
+                               String userId = ((SecurityContext) httpSession
+                                               .getAttribute(SPRING_SECURITY_CONTEXT_KEY))
+                                               .getAuthentication().getName();
+                               return userId;
+                       }
+                       return super.extractUserId(request);
+
+               }
+       }
 }