peony2012 / urlrewritefilter

Automatically exported from code.google.com/p/urlrewritefilter
Other
0 stars 0 forks source link

Allow configuration of http basic authentication when using proxy mode #43

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,
I had a requirement to proxy an incoming url to a backend service that 
used http basic authentication using a service acocunt.  I made some 
modifications to the code to support that functionality.  I can now use a 
<to> url in the following format http://username:password@website.com.  
I've included the modifications below in case you want to add it to your 
trunk:

class org.tuckey.web.filters.urlrewrite.RequestProxy

added import: org.apache.commons.codec.binary.Base64;
modified method setupProxyRequest:

    private static HttpMethod setupProxyRequest(final HttpServletRequest 
hsRequest, final URL targetUrl) throws IOException {
        final String methodName = hsRequest.getMethod();
        final HttpMethod method;
        if ("POST".equalsIgnoreCase(methodName)) {
            PostMethod postMethod = new PostMethod();
            InputStreamRequestEntity inputStreamRequestEntity = new 
InputStreamRequestEntity(hsRequest.getInputStream());
            postMethod.setRequestEntity(inputStreamRequestEntity);
            method = postMethod;
        } else if ("GET".equalsIgnoreCase(methodName)) {
            method = new GetMethod();
        } else {
            log.warn("Unsupported HTTP method requested: " + 
hsRequest.getMethod());
            return null;
        }

        method.setFollowRedirects(false);
        method.setPath(targetUrl.getPath());
        method.setQueryString(targetUrl.getQuery());

        Enumeration e = hsRequest.getHeaderNames();
        if (e != null) {
            while (e.hasMoreElements()) {
                String headerName = (String) e.nextElement();
                if ("host".equalsIgnoreCase(headerName)) {
                    //the host value is set by the http client
                    continue;
                } else if ("content-length".equalsIgnoreCase(headerName)) {
                    //the content-length is managed by the http client
                    continue;
                } else if ("accept-encoding".equalsIgnoreCase(headerName)) 
{
                    //the accepted encoding should only be those accepted 
by the http client.
                    //The response stream should (afaik) be deflated. If 
our http client does not support
                    //gzip then the response can not be unzipped and is 
delivered wrong.
                    continue;
                } else if (headerName.toLowerCase().startsWith("cookie")) {
                    //fixme : don't set any cookies in the proxied 
request, this needs a cleaner solution
                    continue;
                }

                Enumeration values = hsRequest.getHeaders(headerName);
                while (values.hasMoreElements()) {
                    String headerValue = (String) values.nextElement();
                    log.info("setting proxy request parameter:" + 
headerName + ", value: " + headerValue);
                    method.addRequestHeader(headerName, headerValue);
                }
            }
        }

        String authority = targetUrl.getAuthority();
        if (authority.indexOf('@') != -1) {
            authority = authority.substring(0, authority.indexOf('@'));
            String headerValue = "Basic " + new String
(Base64.encodeBase64(authority.getBytes()));
            log.info("setting proxy request 
parameter:Authorization, value: " + headerValue);
            method.addRequestHeader("Authorization", 
headerValue);
        }

        log.info("proxy query string " + method.getQueryString());
        return method;
    }

Original issue reported on code.google.com by psa...@tibco.com on 7 Aug 2009 at 1:43

GoogleCodeExporter commented 9 years ago
+1 for the issue. A fix definitely go into trunk.

I have a few questions though -
1. Why not use targetUrl.getUserInfo instead of targetUrl.getAuthority. It will 
save
us from unnecessary indexOf operation.
2. Does the getUseProxyServer method in this class needs to change too? Right 
now it
returns a ProxyHost. The way it is written (indexOf ":" etc), it will never 
work for
user:pswd@server.com kind of proxy url's.
3. What kind of test cases do we expect for this enhancement?

I am waiting for answers and almost ready with an untested patch.
Paul, your insights please.

Original comment by avl...@gmail.com on 10 Aug 2009 at 6:58

GoogleCodeExporter commented 9 years ago
I don't know too much about proxying requests so I can't really give feedback 
on the
code here, but am happy to accept a well tested patch with test cases.

Original comment by tuc...@gmail.com on 10 Aug 2009 at 11:54

GoogleCodeExporter commented 9 years ago
Thanks for the follow up guys.

1) getUserInfo is the more logical choice.  I'm not 100% familiar with these 
classes 
yet.

2) You're right, however I believe this is a separate issue.  The proxyHost 
that is 
passed to this method is separate from the the targetUrl.

3) At the very least:
+ proxy a regular request to a server with authentication
+ proxy a request that already has basic authentication configured to a server 
with 
authentication.

Original comment by psa...@tibco.com on 12 Aug 2009 at 6:13

GoogleCodeExporter commented 9 years ago

Original comment by avl...@gmail.com on 6 Jan 2010 at 7:11

GoogleCodeExporter commented 9 years ago
Adding a patch for this enhancement. Basic user authentication scheme can now be
supported. This means that once this patch has been applied, the underneath 
would
work as expected -
<rule>
  <from>/some-path-in-app1</from>
  <to type="proxy">http://user:password@internal.app2.com/</to>
</rule>

The patch is untested. I'll attach a revised one with test cases shortly.

Original comment by avl...@gmail.com on 13 Feb 2010 at 9:18

Attachments: