--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.aaa.federation;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+
+class SssdHeadersRequest extends HttpServletRequestWrapper {
+ private static final String headerPrefix = "X-SSSD-";
+
+ public SssdHeadersRequest(HttpServletRequest request)
+ {
+ super(request);
+ }
+
+ public Object getAttribute(String name)
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+name);
+ if (headerValue != null) {
+ return headerValue;
+ } else {
+ return request.getAttribute(name);
+ }
+ }
+
+ @Override
+ public String getRemoteUser()
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+"REMOTE_USER");
+ if (headerValue != null) {
+ return headerValue;
+ } else {
+ return request.getRemoteUser();
+ }
+ }
+
+ @Override
+ public String getAuthType()
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+"AUTH_TYPE");
+ if (headerValue != null) {
+ return headerValue;
+ } else {
+ return request.getAuthType();
+ }
+ }
+
+ @Override
+ public String getRemoteAddr()
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+"REMOTE_ADDR");
+ if (headerValue != null) {
+ return headerValue;
+ } else {
+ return request.getRemoteAddr();
+ }
+ }
+
+ @Override
+ public String getRemoteHost()
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+"REMOTE_HOST");
+ if (headerValue != null) {
+ return headerValue;
+ } else {
+ return request.getRemoteHost();
+ }
+ }
+
+ @Override
+ public int getRemotePort()
+ {
+ HttpServletRequest request = (HttpServletRequest)getRequest();
+ String headerValue;
+
+ headerValue = request.getHeader(headerPrefix+"REMOTE_PORT");
+ if (headerValue != null) {
+ return Integer.parseInt(headerValue);
+ } else {
+ return request.getRemotePort();
+ }
+ }
+
+}
+
+/**
+ * Populate HttpRequestServlet API data from HTTP extension headers.
+ *
+ * When SSSD is used for authentication and identity lookup those
+ * actions occur in an Apache HTTP server which is fronting the
+ * servlet container. After successful authentication Apache will
+ * proxy the request to the container along with additional
+ * authentication and identity metadata.
+ *
+ * The preferred way to transport the metadata and have it appear
+ * seamlessly in the servlet API is via the AJP protocol. However AJP
+ * may not be available or desirable. An alternative method is to
+ * transport the metadata in extension HTTP headers. However we still
+ * want the standard servlet request API methods to work. Another way
+ * to say this is we do not want upper layers to be aware of the
+ * transport mechanism. To achieve this we wrap the HttpServletRequest
+ * class and override specific methods which need to extract the data
+ * from the extension HTTP headers. (This is roughly equivalent to
+ * what happens when AJP is implemented natively in the container).
+ *
+ * The extension HTTP headers are identified by the prefix
+ * "X-SSSD-". The overridden methods check for the existence of the
+ * appropriate extension header and if present returns the value found
+ * in the extension header, otherwise it returns the value from the
+ * method it's wrapping.
+ *
+ */
+public class SssdFilter implements Filter {
+ @Override
+ public void init(FilterConfig fc) throws ServletException {
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest,
+ ServletResponse servletResponse,
+ FilterChain filterChain) throws IOException, ServletException {
+ if (servletRequest instanceof HttpServletRequest) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ SssdHeadersRequest request = new SssdHeadersRequest(httpServletRequest);
+ filterChain.doFilter(request, servletResponse);
+ } else {
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+ }
+}