Validasi tanda tangan di JWT dari login.microsoftonline.com dengan PHP

Saya mencoba menyiapkan layanan sistem masuk tunggal untuk halaman web menggunakan Layanan Azure Active Directory / OpenID Connect dari Microsoft.

Saya sudah mencapainya, di mana saya bisa mendapatkan layanan mereka untuk mengirimi saya id_token, tetapi saya kesulitan dengan cara mengautentikasi/memverifikasi token itu. Karena saya menerimanya dari browser pengguna, bukan melalui permintaan server-ke-server, saya perlu memvalidasinya, bukan?

Untuk mendapatkan tokennya, saya cukup menggunakan 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

(Bagi mereka yang membaca dan mencoba melakukan hal yang sama, butuh waktu lama bagi saya untuk menemukannya, namun Anda dapat menyiapkan id klien Anda di sini: https://apps.dev.microsoft.com/)

Halaman itu kemudian memposting data ke skrip saya, yang terlihat seperti ini:

array(3) {
  ["id_token"]=>
  string(1026) "abc.def.geh"
  ["state"]=>
  string(5) "12345"
  ["session_state"]=>
  string(36) "dd7781aa-74e8-4aa8-ac7e-d3800c5c2247"
}

Sejak saat itu, saya membagi token ID menjadi header, body dan tanda tangan, berdasarkan titik/titik.

Saya kemudian dapat mendekode header base64:

["typ"]=> string(3) "JWT"
["alg"]=> string(5) "RS256"
["kid"]=> string(27) "MnC_VZcATfM5pOYiJHMba9goEKY" 

dan tubuh:

["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 protected]"
["sub"]=> string(43) "oGAnGQ..."
["tid"]=> string(36) "52f161e7..."
["ver"]=> string(3) "2.0"

Sekarang saya punya tanda tangan, tapi saya tidak yakin apa yang harus saya lakukan dengan tanda tangan itu. Saya memahami bahwa saya bisa mendapatkan sertifikat publik yang tepat dari https://login.microsoftonline.com/common/discovery/v2.0/keys seperti yang ditentukan oleh kid di header, tapi saya tidak yakin bagaimana hal itu membantu. Karena saya mengetahui kunci publiknya, saya rasa saya perlu mendekripsi tanda tangan dengannya - benarkah??

Tentunya harus ada cara untuk mengirim permintaan server ke server untuk memverifikasi informasi yang dikirimkan kepada saya dari klien? Misalnya. GET https://login.microsoftonline.com/verfifytoken/[token]

Saya menyiapkan Google SSO, yang sangat mudah dibandingkan dengan ini - Saya yakin saya melewatkan sesuatu, namun tampaknya terlalu rumit!

Bantuan apa pun akan sangat kami hargai - Saya telah membaca dokumentasinya selama berjam-jam sekarang! Saya benar-benar ingin menghindari penggunaan perpustakaan untuk ini, jika memungkinkan, sehingga saya dapat memahami sepenuhnya apa yang terjadi.


person Ben    schedule 21.06.2016    source sumber
comment
Menurut pengalaman saya, kami dapat menggunakan [Otorisasi: id_token] ke dalam header Anda. Dan Anda dapat meminta URL Aplikasi Anda (Anda mendaftarkan Aplikasi menggunakan URL) dengan header ini.   -  person Will Shao - MSFT    schedule 28.06.2016
comment
Ya, menurut saya yang Anda maksud bukan Otorisasi: id_token, tetapi Otorisasi: Pembawa [id_token]?   -  person Konstantin    schedule 25.08.2016
comment
ini mungkin membantu   -  person spottedmahn    schedule 10.08.2017


Jawaban (1)


Karena saya mengetahui kunci publiknya, saya rasa saya perlu mendekripsi tanda tangan dengannya - benarkah??

Sebenarnya yang perlu Anda lakukan adalah memverifikasi sendiri tanda tangannya.

Properti alg memberi tahu Anda bahwa algoritmenya adalah RS256, yang berarti RSA 256. Saya bukan orang Python, tetapi pencarian cepat mengarahkan saya di sini (tidak yakin apakah perpustakaan ini yang terbaik...) tempat Anda dapat memverifikasi tanda tangan. Pesannya adalah dua blok pertama JWT (dipisahkan dengan '.'), dan tanda tangannya adalah blok ketiga.

person Bruno Brant    schedule 15.05.2020