Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

get_token and acurl is not working in Windows 10 with Git Bash/Cygwin terminals

Hi,

My organization has Apigee SaaS with single sign on enabled. For using the management API using single sign on, I wanted to generate the bearer token as suggested in the link.

https://docs.apigee.com/api-platform/system-administration/auth-tools

Issue:

1. I followed the steps as suggested in the resource link and installed sso.cli utility in my machine.

2. I executed get_token and acurl utilities with passcode. I see that sso.cli folder created in the executed location but there is no token generated. No error on the terminal as well.

Could you suggest where is the gap and how to resolve this issue?

Solved Solved
2 9 1,649
1 ACCEPTED SOLUTION

That's lame.

I haven't tried those tools directly. I don't know what the problem might be.

Are you committed to using Bash/Cygwin? If not, here are some things that might help.


The get_token thing is not magic. It's just a wrapper around the API. You could construct the same, yourself, in a simple Powershell module.

You said

My organization has Apigee SaaS with single sign on enabled.

OK, that means you have a zone name. Here's what you should do.

  1. Using your browser, login to apigee, with your zone login. This will be https://ZONENAME.login.apigee.com/
  2. You will need to authenticate according to the requirements of your IDP. Maybe it will be as simple as username + password. Maybe it will be username, password, and a One-time-password or authenticator code. Or maybe some other combination. Anyway, you know what this is. A normal Authentication motion form your IdP.
  3. Now, using the same browser, in a new tab visit https://ZONENAME.login.apigee.com/passcode

    This will display a one-time code in your browser.

    The /passcode endpoint looks at the authenticated browser session, and if it is valid, generates that code.

  4. With a script, POST to https://ZONENAME.login.apigee.com/oauth/token with these params

    headers:

    Content-Type: 'application/x-www-form-urlencoded',
    Authorization: 'Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0'
    	

    body:

    grant_type=password&response_type=token&passcode=ONE_TIME_CODE
    	

    The Authorization header is always the same. It represents the client id and client secret (not really a secret). This is the same id + secret pair used by get_token. It's just an identity for the administrative program. Really Apigee should allow additional sets of these, but for now there is just one.

    The payload is always form-urlencoded. Replace the ONE_TIME_CODE with the thing you got in the previous browser page, the passcode.

    The result will be a JSON payload like this:

    {
        "access_token": "***",
        "token_type": "bearer",
        "refresh_token": "***",
        "expires_in": 43199,
        "scope": "scim.emails.read scim.me openid password.write approvals.me scim.ids.read oauth.approvals",
        "jti": "414a7982-da48-45a7-af66-f562dd553a9c"
    }
    

The access_token you receive in that response is the thing you need to embed into future Admin API calls, as a bearer token. In my case the token is good for 44000 seconds, which is just over 12 hours. Your situation may be different.

You can of course cache that token and re-use it as you wish, up til the expiry time.

After the token has expired, you can get a new token using the refresh_token. The request for that again is a POST to https://ZONENAME.login.apigee.com/oauth/token, and the headers are the same as described above. The body should be as above, form-urlencoded, but with different contents, like this:

refresh_token=REFRESH_TOKEN_HERE&grant_type=refresh_token

Notice you do not need a passcode for this refresh_token request. In response to this, you will get the same access_token payload I described above.

I don't know the lifetime of the refresh token. The access_token might expire in 12 hours, or maybe it's different for your zone, but in any case the access_token response tells you the expiry of the access_token itself. After the access_token expires you can use the refresh token request I just described to get a new access_token (and a new refresh token). But the refresh token also expires, though the payload doesn't tell you when it expires. I believe the lifetime might be 24 hours. It is not documented, as far as I know.

If the refresh token has expired, you will get a 401 from the request I just described, and that means you need to start at step 1 above, and use the passcode.

It doesn't hurt to just periodically refresh the token, every once in a while, and then stash the new token. Then you would always have a token available, and you don't need to continually visit the /passcode endpoint in your browser to get that passcode.

View solution in original post

9 REPLIES 9