Office 365 Rest API – Daemon week authentication

Instead of a client_secret in your request body, you need a client_assertion. This is a bit more complex, but it’s the reason you need that certificate.

Basically you need to build a JSON Web Token and sign it with your certificate using a SHA256 hash. The token is going to look something like this:

Header:

{ 
  "alg": "RS256",
  "x5t": "..." // THUMBPRINT of Cert
}

Payload:

{
  "aud": "https:\\/\\/login.windows.net\\/<The logged in user's tenant ID>\\/oauth2\\/token",
  "exp": 1423168488,
  "iss": "YOUR CLIENT ID",
  "jti": "SOME GUID YOU ASSIGN",
  "nbf": 1423167888,
  "sub": "YOUR CLIENT ID"
}

If you’re still with me, you now need to base64-encode both pieces (separately), then concatenate them with a ‘.’. So now you should have:

base64_header.base64_payload

Now you take that string and sign it with your certificate, using a SHA256 hash. Then base64-encode the result of that, url-encode it, then append to the string, so now you have:

base64_header.base64_payload.base64_signature

Finally, include this in your POST to the token endpoint as the client_assertion parameter, and also include a client_assertion_type parameter set to “urn:ietf:params:oauth:client-assertion-type:jwt-bearer”:

req.set_form_data(
    :grant_type    => 'client_credentials',
    :redirect_uri  => 'http://spready.dev',
    :resource      => 'https://outlook.office365.com/',
    :client_id     => '== Client ID ==',
    :client_assertion_type => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
    :client_assertion => 'base64_header.base64_payload.base64_signature'
  )

I hope that helps! This is all based on my research into how ADAL does it, and I haven’t tested it myself in Ruby.

Leave a Comment