Process for creating a Jamf-token?

lashomb
Contributor II

I couldn't find information on this anywhere... the UAPI docs let you generate a token on the docs page, but I have no idea how long that token is good for, where its managed, or if it can be managed. In the Jamf Pro API docs they also show base64 encoding a Basic Auth setup. Does anyone have any more information into the auth methods for UAPI?

8 REPLIES 8

lashomb
Contributor II

More importantly, how do I revoke this token that was just created?

BradB
New Contributor III

@lashomb We're working to get some official documentation up on the Developer Portal for the Jamf Pro API. In the meantime, you can request a token by sending a POST to /uapi/auth/tokens with the header “Authorization: Basic YOUR_CREDENTIALS” where YOUR_CREDENTIALS is base64 encoded credentials for an appropriate Jamf Pro server account. You'll receive a response back containing a token and an expiration epoch. You can use the generated token to make calls to any other Jamf Pro API endpoint by including it in a header using the format “Authorization: jamf-token <TOKEN_VALUE>”.

Tokens expire after 30 minutes by default, but you can generate a new token with the same information using the /uapi/auth/keepAlive endpoint. Simply send a POST to the endpoint with the existing token in an Authorization header like you would to any other endpoint. The keepAlive endpoint will respond with a new token and expiration and will invalidate the previous token.

Keep an eye on the Developer Portal for more Jamf Pro API documentation coming out soon. Also make sure to check the release notes for each Jamf Pro release to see what's new in the API.

BradB
New Contributor III

@lashomb you can revoke the token using the /auth/invalidateToken endpoint.

jphillips
Release Candidate Programs Tester

@beckerbm Has there been any updates on the documentation for the new api? I'm having issues authenticating as well. I can get a token back, but when I try to do a simple get to test, I get a 401 error.

BradB
New Contributor III

@jphillips nothing public, we're rearranging some things on the Jamf Developer Portal so getting this documentation out there is taking a little longer than expected. Can you give more details on the specific call you're trying to make? Also are you trying to use curl or something like Postman/Insomnia?

jphillips
Release Candidate Programs Tester

@beckerbm We're creating an iOS app that interacts with the api to update an ext attribute. Using Alamofire and SwiftyJSON.

I setup the api username/password and encode into base64. I use Alamofire to get the token. This works well and I get the token back.

As a test, I try to do a get on a specific mobile device just to see if I can get info back on it (so that I can make sure everything is communicating):

let urlExtAttr = managedApp.jssURL + "/uapi/inventory/obj/mobileDevice/(managedApp.deviceID)"
let extURLWithoutSpaces:String = urlExtAttr.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!

let uapiHeaders = [ "Authorization": "jamf-token (token)", "Accept": "application/json", "Content-Type": "application/json" ]

Alamofire.request(extURLWithoutSpaces, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: uapiHeaders) .responseJSON { response in print(response) }

-- The printed response --
SUCCESS: { errors = ( ); httpStatus = 401;
}

BradB
New Contributor III

@jphillips I'm not super familiar with those libraries but I believe everything looks ok. I would recommend switching from "jamf-token" to "Bearer" for your Authorization header. We added that functionality in Jamf Pro 10.8 to conform more closely to the JWT standard (http://docs.jamf.com/10.8.0/jamf-pro/release-notes/What's_New.html). "jamf-token" will continue to work but we do intend to deprecate it at some point in the future.

I would go through and try to log out each step of the process to ensure that nothing is getting garbled in the code (URL, token, etc.). I'd also recommend trying this request manually in curl or Postman if you haven't done so already just to make sure it's not your Jamf Pro instance that is causing the issue.

james_felton
New Contributor

@jphillips

I've tested this code below, hope it helps. I offer it with no warranties or guarantees.

I created a struct that uses the Decodable protocol so Swift can parse the auth token with JSONDecoder:

struct Auth: Decodable { let token: String let expires: Int64 }

Here is the code to create the headers, and make the requests for both /uapi/auth/tokens and /uapi/inventory/obj/mobileDevice/{id}

let authUrl = managedApp.jssURL + "/uapi/auth/tokens" let mobileDeviceUrl = managedApp.jssURL + "/uapi/inventory/obj/mobileDevice/(managedApp.deviceID)/detail" let credentialData = "(user):(password)".data(using: String.Encoding.utf8)! let base64Credentials = credentialData.base64EncodedString() let basicAuthHeader = [ "Authorization": "Basic (base64Credentials)"] Alamofire.request(authUrl, method: .post, parameters: nil, encoding: JSONEncoding.default, headers: basicAuthHeader) .responseJSON { response in guard let data = response.data else { NSLog("error retrieving data from response") return } guard let extURLWithoutSpaces = mobileDeviceUrl.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) else { NSLog("Could not create mobile device URL from (mobileDeviceUrl)") return } var token: Auth do { token = try JSONDecoder().decode(Auth.self, from: data) } catch let error { NSLog("Could not obtain token form Jamf Pro: (error.localizedDescription)") return } let uapiHeaders = [ "Authorization": "Bearer (token.token)"] Alamofire.request(extURLWithoutSpaces, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: uapiHeaders) .responseJSON { response in print(response) } }