{"id":3189,"date":"2015-02-06T10:29:56","date_gmt":"2015-02-06T18:29:56","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=3189"},"modified":"2015-02-06T10:29:56","modified_gmt":"2015-02-06T18:29:56","slug":"requesting-an-aad-token-with-a-certificate-without-adal","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2015\/02\/06\/requesting-an-aad-token-with-a-certificate-without-adal\/","title":{"rendered":"Requesting an AAD Token with a Certificate &ndash; without ADAL"},"content":{"rendered":"<p>I am sure you have seen the exciting <a href=\"http:\/\/blogs.technet.com\/b\/ad\/archive\/2015\/02\/04\/using-azure-ad-to-build-daemon-applications-that-call-office-365-apis.aspx\">news about daemon apps &amp; O365<\/a> that Alex shared a couple of days ago.<\/p>\n<p>That post reinvigorated interest in the token request flow based on certificates. We have <a href=\"https:\/\/github.com\/AzureADSamples\/Daemon-CertificateCredential-DotNet\">a complete end to end sample<\/a> giving you step by step guidance on how to implement that flow with ADAL .NET, but we don\u2019t yet have detailed protocol documentation for it. <br \/>We will get to it, but in the meanwhile: if you need to reproduce the same flow in a different platform, a good trick is to run the e2e sample and observe a trace of the traffic it generates. To give you a headstart, here there\u2019s a breakdown of the token request it generates \u2013 mildy formatted for your screens:<\/p>\n<p><font face=\"Consolas\">POST <\/font><a href=\"https:\/\/login.windows.net\/contoso.onmicrosoft.com\/oauth2\/token\"><font face=\"Consolas\">https:\/\/login.windows.net\/contoso.onmicrosoft.com\/oauth2\/token<\/font><\/a><font face=\"Consolas\"> HTTP\/1.1<br \/>Content-Type: application\/x-www-form-urlencoded<br \/>client-request-id: a2ef0cd8-60e5-4620-ac66-6f2a344e075b<br \/>return-client-request-id: true<\/p>\n<p>Host: login.windows.net<br \/>Content-Length: 986<br \/>Expect: 100-continue<br \/>Connection: Keep-Alive<\/font><\/p>\n<p><font face=\"Consolas\">resource=https%3A%2F%2Fcontoso.onmicrosoft.com%2FTodoListService<br \/>&amp;client_id=82692da5-a86f-45c9-9d53-2f88d51b478b<br \/>&amp;client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer<br \/>&amp;client_assertion=eyJhbGciOi[\u2026a lot of stuff\u2026]-j5UBo1A<br \/>&amp;grant_type=client_credentials<\/font><\/p>\n<p>The main things to notice here:<\/p>\n<p>1) it\u2019s a POST to the token endpoint<\/p>\n<p>2) it is a client_credentials grant, as expected<\/p>\n<p>3) you need to specify as client_assertion_type the magic value <font face=\"Consolas\">urn:ietf:params:oauth:client-assertion-type:jwt-bearer<\/font><\/p>\n<p>The other thing of interest is in the client_assertion itself, which is the artifact in which the certificate actually comes into play: it\u2019s an assertion you need to create and sign with the certificate you registered as credential for your application. ADAL does this for you, ut if you want to work directly at the protocol level you\u2019ll have to do it yourself. Here there\u2019s how the JWT of the assertion looks like, as decoded by <a href=\"https:\/\/developers.google.com\/wallet\/digital\/docs\/jwtdecoder\">Google\u2019s JWT decoder<\/a>.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/image.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/image_thumb.png\" width=\"902\" height=\"452\"><\/a><\/p>\n<p>Things to notice:<\/p>\n<p>1) As this is signed with a certificate, the algorithm is RS256<\/p>\n<p>2) subject and issuer are the same \u2013 the identifier of the client! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile1.png\"><\/p>\n<p>3) the assertion is scoped to the token endpoint, its intended destination<\/p>\n<p>&nbsp;<\/p>\n<p>That\u2019s it! It should be really straightforward for you to use any JWT library on your favorite platform to produce the above. Have fun! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile1.png\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am sure you have seen the exciting news about daemon apps &amp; O365 that Alex shared a couple of days ago. That post reinvigorated interest in the token request flow based on certificates. We have a complete end to end sample giving you step by step guidance on how to implement that&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3189","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3189","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=3189"}],"version-history":[{"count":1,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3189\/revisions"}],"predecessor-version":[{"id":3190,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3189\/revisions\/3190"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=3189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=3189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=3189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}