While the method described in this post still work. Microsoft are moving to what they call secure app model. Meaning that password grant is deprecated and you will need to use a refresh token model. I will update this post to reflect the changes as soon as possible
If you’re not familiar with the Microsoft Cloud Service Provider program it’s in short a program to easier let service providers manage their customers tenants and subscriptions within Azure and Office 365 from a centralized platform.
Apart from a very limited web portal it have a set of API’s and SDK’s to build your own solutions – wich I assume is prefered from Microsoft and the service provider. For a project I needed to authenticate against the REST API using Powershell and then retrieve some information about each tenant, who would have thought that could be so much work
Here’s what I said.
That’s fine, I will have it to you in an hour.
For your reference, this is the API I am working with: Partner Center Swagger
An hour later I did have authentication in place, but I was unable to retrieve any information from our customers. After digging through the documentation I found that the customer endpoints required “App + User Authentication” where I had only authenticated with AppId and App Secret.
After spending too much time decifer the C# examples on how you authenticate with app and user against the CSP Rest API i finally had a working Powershell function.
These are the steps required
- Generate a token from Azure AD by calling https://login.microsoft.com/tenant-name/oauth/token
- Specified with the resource you want to access (partner center api), client id, username and password, correct grant type and scope
- Use the AAD token to authenticate against partnercenter/generatetoken and recieve a correct User + App jwt_token
- Use the jwt token to further authenticate against endpoints you preffer
If you ever find your self in a situation where you need to authenticate against the CSP REST API as app + user, here is a function to do it.
Be aware that the function does require a credential object, but when you atuhenticate against AAD the password is decoded and sent in the post request.