I'm trying to set up a single-sign-on service for a web page using the Azure Active Directory / OpenID Connect services from Microsoft.
I've got some of the way there, in that I can get their service to send me an id_token, but I'm struggling with how to authenticate/verify that token. As I received it from the users browser, rather than via a server-to-server request, I need to validate it, right?
To get the token, I just use a link:
https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?client_id=[myclientid]&response_type=id_token&redirect_uri=https://localhost/ssotest.php&response_mode=form_post&scope=openid+profile&state=12345&nonce=678910
(For those reading trying to do the same, it took me ages to find, but you can set up your client id here: https://apps.dev.microsoft.com/)
That page then posts data to my script, which looks something like this:
array(3) {
["id_token"]=>
string(1026) "abc.def.geh"
["state"]=>
string(5) "12345"
["session_state"]=>
string(36) "dd7781aa-74e8-4aa8-ac7e-d3800c5c2247"
}
From that point, I split up the ID token in to the header, body and signature, based on the periods/full-stops.
I can then base64decode the header:
["typ"]=> string(3) "JWT"
["alg"]=> string(5) "RS256"
["kid"]=> string(27) "MnC_VZcATfM5pOYiJHMba9goEKY"
and the body:
["aud"]=> string(36) "[client_id]"
["iss"]=> string(75) "https://login.microsoftonline.com/52f161e7.../v2.0"
["iat"]=> int(1466523280)
["nbf"]=> int(1466523280)
["exp"]=> int(1466527180)
["ipaddr"]=> string(15) "111.111.111.111"
["name"]=> string(12) "Mr E Xample"
["nonce"]=> string(6) "678910"
["oid"]=> string(36) "c3beeb42..."
["preferred_username"]=> string(23) "email@example.co.uk"
["sub"]=> string(43) "oGAnGQ..."
["tid"]=> string(36) "52f161e7..."
["ver"]=> string(3) "2.0"
Now I have a signature, but I'm not really sure what to do with it. I understand I can get the right public certificate from https://login.microsoftonline.com/common/discovery/v2.0/keys as specified by the kid in the header, but I'm not sure how that helps. As I know the public key, I guess I need to decrypt the signature with it - is that right??
Surely there must be a way to send a server to server request to verify the information sent to me from the client? E.g. GET https://login.microsoftonline.com/verfifytoken/[token]
I set up Google SSO, which was a breeze compared to this - I'm sure I'm missing something, but it really does seem over complicated!
Any help would be very much appreciated - I've been reading the documentation for many hours now! I'd really like to avoid using libraries for this, if possible, so I can fully understand what is happening.