Populate HttpRequestServlet API data from HTTP extension headers.
[aaa.git] / aaa-authn-federation / src / main / java / org / opendaylight / aaa / federation / SssdFilter.java
1 /*
2  * Copyright (C) 2014 Red Hat
3  * All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.aaa.federation;
10
11 import java.io.IOException;
12
13 import javax.servlet.Filter;
14 import javax.servlet.FilterChain;
15 import javax.servlet.FilterConfig;
16 import javax.servlet.ServletException;
17 import javax.servlet.ServletRequest;
18 import javax.servlet.ServletResponse;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletRequestWrapper;
21
22
23 class SssdHeadersRequest extends HttpServletRequestWrapper {
24     private static final String headerPrefix = "X-SSSD-";
25
26     public SssdHeadersRequest(HttpServletRequest request)
27     {
28         super(request);
29     }
30
31     public Object getAttribute(String name)
32     {
33         HttpServletRequest request = (HttpServletRequest)getRequest();
34         String headerValue;
35
36         headerValue = request.getHeader(headerPrefix+name);
37         if (headerValue != null) {
38             return headerValue;
39         } else {
40             return request.getAttribute(name);
41         }
42     }
43
44     @Override
45     public String getRemoteUser()
46     {
47         HttpServletRequest request = (HttpServletRequest)getRequest();
48         String headerValue;
49
50         headerValue = request.getHeader(headerPrefix+"REMOTE_USER");
51         if (headerValue != null) {
52             return headerValue;
53         } else {
54             return request.getRemoteUser();
55         }
56     }
57
58     @Override
59     public String getAuthType()
60     {
61         HttpServletRequest request = (HttpServletRequest)getRequest();
62         String headerValue;
63
64         headerValue = request.getHeader(headerPrefix+"AUTH_TYPE");
65         if (headerValue != null) {
66             return headerValue;
67         } else {
68             return request.getAuthType();
69         }
70     }
71
72     @Override
73     public String getRemoteAddr()
74     {
75         HttpServletRequest request = (HttpServletRequest)getRequest();
76         String headerValue;
77
78         headerValue = request.getHeader(headerPrefix+"REMOTE_ADDR");
79         if (headerValue != null) {
80             return headerValue;
81         } else {
82             return request.getRemoteAddr();
83         }
84     }
85
86     @Override
87     public String getRemoteHost()
88     {
89         HttpServletRequest request = (HttpServletRequest)getRequest();
90         String headerValue;
91
92         headerValue = request.getHeader(headerPrefix+"REMOTE_HOST");
93         if (headerValue != null) {
94             return headerValue;
95         } else {
96             return request.getRemoteHost();
97         }
98     }
99
100     @Override
101     public int getRemotePort()
102     {
103         HttpServletRequest request = (HttpServletRequest)getRequest();
104         String headerValue;
105
106         headerValue = request.getHeader(headerPrefix+"REMOTE_PORT");
107         if (headerValue != null) {
108             return Integer.parseInt(headerValue);
109         } else {
110             return request.getRemotePort();
111         }
112     }
113
114 }
115
116 /**
117  * Populate HttpRequestServlet API data from HTTP extension headers.
118  *
119  * When SSSD is used for authentication and identity lookup those
120  * actions occur in an Apache HTTP server which is fronting the
121  * servlet container. After successful authentication Apache will
122  * proxy the request to the container along with additional
123  * authentication and identity metadata.
124  *
125  * The preferred way to transport the metadata and have it appear
126  * seamlessly in the servlet API is via the AJP protocol. However AJP
127  * may not be available or desirable. An alternative method is to
128  * transport the metadata in extension HTTP headers. However we still
129  * want the standard servlet request API methods to work. Another way
130  * to say this is we do not want upper layers to be aware of the
131  * transport mechanism. To achieve this we wrap the HttpServletRequest
132  * class and override specific methods which need to extract the data
133  * from the extension HTTP headers. (This is roughly equivalent to
134  * what happens when AJP is implemented natively in the container).
135  *
136  * The extension HTTP headers are identified by the prefix
137  * "X-SSSD-". The overridden methods check for the existence of the
138  * appropriate extension header and if present returns the value found
139  * in the extension header, otherwise it returns the value from the
140  * method it's wrapping.
141  *
142  */
143 public class SssdFilter implements Filter {
144     @Override
145     public void init(FilterConfig fc) throws ServletException {
146     }
147
148     @Override
149     public void destroy() {
150     }
151
152     @Override
153     public void doFilter(ServletRequest servletRequest,
154                          ServletResponse servletResponse,
155                          FilterChain filterChain) throws IOException, ServletException {
156         if (servletRequest instanceof HttpServletRequest) {
157             HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
158             SssdHeadersRequest request = new SssdHeadersRequest(httpServletRequest);
159             filterChain.doFilter(request, servletResponse);
160         } else {
161             filterChain.doFilter(servletRequest, servletResponse);
162         }
163     }
164 }