{"id":5545,"date":"2019-05-13T04:58:29","date_gmt":"2019-05-13T04:58:29","guid":{"rendered":"https:\/\/blogs.aaddevsup.xyz\/?p=5545"},"modified":"2022-05-04T15:34:59","modified_gmt":"2022-05-04T15:34:59","slug":"understanding-azure-ad-token-signing-certificate-kid","status":"publish","type":"post","link":"https:\/\/blogs.aaddevsup.xyz\/2019\/05\/understanding-azure-ad-token-signing-certificate-kid\/","title":{"rendered":"Understanding Azure AD token signing certificate (kid)"},"content":{"rendered":"
Upon successful authentication, Azure AD issues a signed JWT token (id token or access token). The resource application needs to know the public key of the certificate used sign the token in order to validate<\/a> the token signature. Depending upon the type (OAuth2 or SAML Application) of the resource application, the steps to obtain the pubic key information are different. An OWIN asp.net application can throw the following error when it’s not able to find the kid to validate the token signature:<\/p>\n IDX10501: Signature validation failed. Unable to match ‘kid’ or IDX10501: Signature validation failed. Unable to match key<\/strong><\/span><\/p>\n To demonstrate the concept, I have registered the following 3 Applications in Azure AD:<\/p>\n bhfrontend app<\/strong> – used to sign in and get an access token to one of the following backend app: <\/p>\n <\/p>\n <\/p>\n Use Postman’s Authorization Code<\/a> flow to obtain an access token for the bhbackend app. For oauth2 applications, use the following keys discovery endpoint to find the public key of the signing certificate: https:\/\/login.microsoftonline.com\/common\/discovery\/keys <\/strong><\/span><\/p>\n I am using https:\/\/jwt.ms<\/a> to decode the access token and kid in the access token should match one of the 3 kids at the end point.<\/p>\n Note<\/strong><\/span>: The application demonstrated here is a V1 app. For V2 app, use https:\/\/login.microsoftonline.com\/common\/discovery\/v2.0\/keys<\/a> instead of.<\/p>\n <\/p>\n Again, use Postman to get an access token for the SharepointSAMLTest App. Azure AD uses the certificate created for this application to sign the token. For this scenario, we have to use the following keys discovery endpoint to get to the public key of that certificate. The App ID below can be found in the Properties section of that Enterprise App.<\/p>\n https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/discovery\/keys?appid=<\/span><SAML App ID><\/span><\/strong><\/span> <\/p>\n The above keys discovery endpoint can be obtained from the app-specific metadata endpoint:<\/p>\n https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/.well-known\/openid-configuration?appid=<\/span><SAML App ID><\/span><\/strong><\/span><\/p>\n This is also documented below for both V1 and V2 endpoint:<\/p>\n V2 OpenID Connect protocol<\/a> If your app has custom signing keys as a result of using the claims-mapping<\/a> feature, you must append an Typically, you would use this metadata document to configure an OpenID Connect library or SDK; the library would use the metadata to do its work. However, if you’re not using a pre-built OpenID Connect library, you can follow the steps in the remainder of this article to do sign-in in a web app by using the Microsoft identity platform endpoint.<\/p>\n<\/blockquote>\n In the example above I use the bhfrontend application as OAuth2 application for sign in. If this application is a SAML Application with Single Sign-On feature enabled, the same Signature Validation error can occur here. To resolve the error one should use the application-specific metadata endpoint. See below examples for both the OpenID Connect OWIN middleware of JWT Bearer Authentication middleware usage of the MetadataAddress property.<\/p>\n OpenID Connect middleware:<\/strong> JWT Bearer Authentication middleware:<\/strong> Microsoft.Identity.Web Web App Authentication:<\/strong><\/p>\n Microsoft.Identity.Web Web API Authentication:<\/strong><\/p>\n I hope this blog post provides clarification on how to get to the public key of the signing certificate to validate the token signature. Please leave us a comment if you find this helpful. If you want to learn more about Azure AD signing keys rollover, you should take a look at this<\/a> article.<\/p>\n\n\n <\/p>\n","protected":false},"excerpt":{"rendered":" Introduction Upon successful authentication, Azure AD issues a signed JWT token (id token or access token). The resource application needs to know the public key of the certificate used sign the token in order to validate the token signature. Depending upon the type (OAuth2 or SAML Application) of the resource application, the steps to obtain the pubic key information are different. An OWIN asp.net application can throw the following error…<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[24,150,84,96],"class_list":["post-5545","post","type-post","status-publish","format-standard","hentry","category-azure-ad","tag-access-token","tag-certficate","tag-how-to","tag-keys"],"_links":{"self":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/5545"}],"collection":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/comments?post=5545"}],"version-history":[{"count":39,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/5545\/revisions"}],"predecessor-version":[{"id":8816,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/5545\/revisions\/8816"}],"wp:attachment":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/media?parent=5545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/categories?post=5545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/tags?post=5545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}The setup:<\/h1>\n
bhbackend app<\/strong> – backend oauth2 application which the bhfrontend app requests an access token for
SharepointSAMLTest app<\/strong> – backend SAML application which the bhfrontend app requests an access token for<\/p>\n\n
\n
\n
OAuth2 resource application<\/h1>\n
SAML Resource Application<\/h1>\n
<\/span><\/p>\n
V1 OpenID Connect protocol<\/a><\/p>\n\n
appid<\/code> query parameter containing the app ID in order to get a
jwks_uri<\/code> pointing to your app’s signing key information. For example:
https:\/\/login.microsoftonline.com\/{tenant}\/v2.0\/.well-known\/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e<\/code> contains a
jwks_uri<\/code> of
https:\/\/login.microsoftonline.com\/{tenant}\/discovery\/v2.0\/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e<\/code>.<\/p>\n
use OpenIdConnectAuthenticationOptions.MetadataAddress Property<\/a><\/p>\napp.UseOpenIdConnectAuthentication(\n new OpenIdConnectAuthenticationOptions\n {\n \/\/ Sets the ClientId, authority, RedirectUri as obtained from web.config\n ClientId = clientId,\n Authority = authority,\n RedirectUri = redirectUri,\n MetadataAddress = \"https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/.well-known\/openid-configuration?appid=<\/span><SAML App ID>\"<\/span><\/strong><\/span>\n PostLogoutRedirectUri = redirectUri,\n }<\/pre>\n
use JwtBearerOptions.MetadataAddress<\/a> Property<\/p>\napp.UseJwtBearerAuthentication(new JwtBearerOptions\n{\n Audience = \"...\",\n Authority = \"...\",\n MetadataAddress = \"https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/.well-known\/openid-configuration?appid=<\/span><SAML App ID>\"<\/span><\/strong><\/span>,\n TokenValidationParameters = new TokenValidationParameters\n {\n ...\n }\n});<\/pre>\n
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)\n .EnableTokenAcquisitionToCallDownstreamApi()\n .AddInMemoryTokenCaches();
\nservices.Configure<MicrosoftIdentityOptions>(options =>\n{\n options.MetadataAddress = \"https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/.well-known\/openid-configuration?appid=<\/span><SAML App ID>\"<\/span><\/strong><\/span>;\n});<\/pre>\nusing Microsoft.AspNetCore.Authentication.JwtBearer;
\nservices.AddMicrosoftIdentityWebApiAuthentication(Configuration);
\nservices.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme,options =>\n{\n options.MetadataAddress = \"https:\/\/login.microsoftonline.com\/<\/span><tenant name><\/span>\/.well-known\/openid-configuration?appid=<\/span><SAML App ID>\"<\/span><\/strong><\/span>;\n});<\/pre>\nConclusion<\/h1>\n