401 Unauthorized error when deploying via Maven Plugin

Not applicable

Hi,

I want to be able to post my API changes to /v1/organizations/{org}/apis via Maven. If I post via a standalone rest client, the post is succesfull. If I post via Maven, I recieve a 401 Unauthorized error back. I am running the following (note, I am behind a corporate proxy):

mvn clean install -Ptest -Dapigee.org=<org> -Dapigee.username=<apigee username> -Dapigee.password=<apigee password> -Dhttps.proxyUser=<corporate proxy user> -Dhttps.proxyPassword=<corporate proxy password> -DproxySet=true -Dhttps.proxyHost=<proxy host> -Dhttps.proxyPort=<port>

Things to note:

  • I am running forecastweatherapi from this maven example project
  • If I run from outside of the corporate proxy, it works fine (the API is uploaded succesfully via the same maven command)
  • If I debug and put logging into the maven plugin, I can see the password hash and headers are definately correct
  • The response I get is from Apigee, it has gotten passed our proxy and is not a proxy auth failure

I am out of ideas, any help much appreciated.

Thanks,

Simon.

1 9 2,235
9 REPLIES 9

@Sai Saran Vaidyanathan have you seen this before?

Not applicable

I have just done a TCP/IP spy to intercept what Maven is sending out. The headers look correct, and I have copied and pasted the HTTP headers into my rest client and it works? It has to be something to do with the corporate proxy, but I can't see how as the Unauthorized is a response from Apigee?

@Simon Pink

Did you try posting it in your network using your rest client ? Did that work ?

Can you share the maven logs ? Also which version of the plugin are you using ? Also can you share your profile entry from the shared-pom.xml

Something like this

<profile>
            <id>test</id>
            <properties>
                <org>testmyapi</org>  <!-- default org, replace with default org to avoid passing parameter e.g. -Dorg testmyapi -->
                <options>validate</options>  <!-- default org, replace with default org to avoid passing parameter e.g. -Dorg testmyapi -->
                <apigee.profile>test</apigee.profile>
                <apigee.env>test</apigee.env>
                <apigee.hosturl>https://api.enterprise.apigee.com</apigee.hosturl>
                <apigee.apiversion>v1</apigee.apiversion>
                <apigee.org>${org}</apigee.org>
                <apigee.username>${username}</apigee.username>
                <apigee.password>${password}</apigee.password>
                <apigee.options>${options}</apigee.options>
                <apigee.revision>${revision}</apigee.revision> <!-- used while trying to update revision, use when option=update only -->
            </properties>
        </profile>

@Sai Saran Vaidyanathan thanks for your response

I can successfully use a standalone rest client via the proxy from within our corporation. I copied all of the HTTP headers which I had system.out'd from the maven plugin (see below), and it works. All very odd. I would expect it to fail, as it _seems_ to be exactly what the maven plugin is doing.

I hacked the maven plugin to put extra logging in, so here it is:

Profile

<profile>
    <id>test</id>
    <properties>
        <org>pinky</org>
        <options>validate</options>
        <apigee.profile>test</apigee.profile>
        <apigee.env>test</apigee.env>
        <apigee.hosturl>https://api.enterprise.apigee.com</apigee.hosturl>
        <apigee.apiversion>v1</apigee.apiversion>
        <apigee.org>${org}</apigee.org>
        <apigee.username>${username}</apigee.username>
        <apigee.password>${password}</apigee.password>
        <apigee.options>${options}</apigee.options>
        <!--apigee.override.delay>10</apigee.override.delay-->
        <!--apigee.delay>1000</apigee.delay-->                             
    </properties>
</profile>        

Request

POST https://api.enterprise.apigee.com/v1/organizations/pinky/apis?action=import&name=forecastweatherapi&...
accept: [application/json]
accept-encoding: [gzip]
authorization: Basic [Not shown in log]
content-type: application/octet-stream
[Request
body contains data, not shown]

headers: [{accept=[application/json], accept-encoding=[gzip], authorization=[Basic MY_HASHED_AUTH]}]

Response

httpResponse.getHeaders(): [{age=[0],
cache-control=[proxy-revalidate], content-length=[0],
content-type=[application/json], date=[Thu, 16 Jun 2016 10:33:06 GMT],
www-authenticate=[Basic realm="/organizations/pinky/apis"], prox
y-support=[Session-based-authentication],
set-cookie=[BCSI-CS-29697961c7e3fc52=1; Path=/], connection=[Keep-Alive],
server=[Apigee Router]}]

httpResponse.getStatusCode(): [401]

11:33:07,123 ERROR RestUtil:430 - 401 Unauthorized

I have proxied the API post via Apigee so that I could trace the headers. Of note in the trace session:

  • If we run via Maven, the Authorization header is being stripped out. This is odd as I can see it is being set correctly in the plugin.
  • If we run via a rest client (still behind our proxy), the header does not get stripped out
  • If I hard code the exact same headers in the maven plugin that I can see coming in from the rest client (cache control, user agent and cookie), I sometimes get a 401 (no auth header) and sometimes a 404 (with auth header)

All very strange and confusing. It almost has to be something to do with our network proxies somehow, just not sure how. Particualry strange is the difference between the maven plugin and the rest client.

Interesting.. Couple of questions:

  1. Did you try calling the Management API directly through Postman? I am assuming you did and it worked, please clarify as I am not sure from your reply above.
  2. If you have not tried it via POSTMAN within your Corportate proxy, can you try that and see if it works
  3. In your maven command, I see you are passing other arguments like proxy*? Why do you need a proxy when I think its working directly using POSTMAN
  4. Can you also check if you have any config in your maven settings.xml that is conflicting ?
  5. Can you zip the entire folder and attach it here ?

Not applicable

It was definitely our internal proxy causing havoc. As a work around I:

  • Put the Authorization into a different header, lets say "X-MyAuth"
  • Created a Apigee Management Proxy
  • In the Apigee proxy, I move the value of "X-MyAuth" into the proper "Authorization" header
  • The Apigee proxy then passes the request to the management API

@Simon Pink

So your maven plugin is calling the Apigee proxy instead of calling the Management API directly?

If the Management API call is working on your Rest client (within your network), I am not sure why its failing via the maven command. Did you try without the proxy arguments ?

Yes, I have changed the plugin, and it is calling my own proxy.

I think because my rest client gets a session with the proxy, where as the maven doesn't - I can see a session token being passed in the headers when using the rest client.

Current solution works, although it is a bit of a work around until we figure out exactly what the proxy is doing.