aboutsummaryrefslogtreecommitdiffstats
path: root/upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/SssdFilter.java
blob: 9223c6dd268ccb55da408d0c431113d32e339542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (c) 2014, 2015 Red Hat, Inc. and others.  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);
        }
    }
}