Error calling CF API login one time passcode

382 views Asked by At

I am working with the CF API RESTful services. Trying to get an access token from cloud foundry's UAA API using https://login..../oauth/token web method.

I have verified that headers & body content is correct, but calling the api always returns a 400 error code with message missing grant type.

I have implemented this call in Objective-C, Swift & now Python. All tests return the same result. Here is my code example in Python:

import json
import requests
import urllib

params = {"grant_type": "password",
          "passcode": "xxx"
          }
url = "https://login.system.aws-usw02-pr.ice.predix.io/oauth/token"
headers = {"Authorization": "Basic Y2Y6", "Content-Type": "application/json", "Accept": "application/x-www-form-urlencoded"}

encodeParams = urllib.parse.urlencode(params)
response = requests.post(url, headers=headers, data=encodeParams)
rjson = response.json()
print(rjson)

Each time I run this, I get the response error invalid request, Missing grant type

Any help would be greatly appreciated.

1

There are 1 answers

2
Daniel Mikusa On BEST ANSWER

Your code mostly worked for me, although I used a different UAA server.

I had to make only one change. You had the Accept and Content-Type headers flipped around. Accept should be application/json because that's the format you want back, and Content-Type should be application/x-www-form-urlencoded because that's the format you are sending.

See the API Docs for reference.

import json
import requests
import urllib
import getpass

UAA_SERVER = "https://login.run.pivotal.io"

print("go to {}/passcode".format(UAA_SERVER))

params = {
    "grant_type": "password",
    "passcode": getpass.getpass(),
}

url = "https://login.run.pivotal.io/oauth/token"
headers = {
    "Authorization": "Basic Y2Y6",
    "Content-Type": "application/x-www-form-urlencoded",
    "Accept": "application/json"
}

encodeParams = urllib.parse.urlencode(params)
response = requests.post(url, headers=headers, data=encodeParams)
rjson = response.json()
print(json.dumps(rjson, indent=4, sort_keys=True))

I made a couple other minor changes, but they should affect the functionality.

  1. Use getpass.getpass() to load the passcode.
  2. Set the target server as a variable.
  3. Pretty print the JSON response.

The only other thing to note, is that the OAuth2 client you use must be allowed to use the password grant type. It looks like you're using the same client that the cf cli uses, so if your UAA server is part of a standard Cloud Foundry install that is likely to be true, but if it still doesn't work for you then you may need to talk with an administrator and make sure the client is set up to allow this.