I have spent quite a bit of time getting our .NET MVC web application to integrate with Azure Active Directory B2C, with reasonable success, using a custom profile to allow users of other Azure Active Directories to log in to us.
Now I want to incorporate an API, roughly following this process:
https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi
I say roughly because I'm trying to fit this functionality into an application that's already been under development for several months.
I'm using Postman to hit this URL a and get a bearer token: https://login.microsoftonline.com/ourtenant.onmicrosoft.com/oauth2/token
I use the grant_type=client_credentials, and the client_id and client_secret specified in Active Directory (added in the the "not-B2C" App registrations blade because apparently B2C doesn't yet support the client_credentials flow)
It appears to work fine and I get a response like this:
{
"token_type": "Bearer",
"expires_in": "3599",
"ext_expires_in": "0",
"expires_on": "1513906161",
"not_before": "1513902261",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyIsImtpZCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMvIiwiaWF0IjoxNTEzOTAyMjYxLCJuYmYiOjE1MTM5MDIyNjEsImV4cCI6MTUxMzkwNjE2MSwiYWlvIjoiWTJOZ1lKaTJWbkhKTXQwNUcrZmMrL2pFNmRQLzdRQT0iLCJhcHBpZCI6IjZkZmVkNGVkLTU2ZDktNDQ5Ny04M2JhLTkzOWJmNGI3OGUyNSIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzdiNjVkNjQ0LTE0MzQtNDFkNC1hMWEwLTgyNWVmODA5MDJkMy8iLCJvaWQiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJzdWIiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJ0ZW5hbnRfcmVnaW9uX3Njb3BlIjoiTkEiLCJ0aWQiOiI3YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMiLCJ1dGkiOiJjV2lzVmxDRDEwdW9Ra3BHbWRBdkFBIiwidmVyIjoiMS4wIn0.BiXHI5Sp0t2k_npJYdWjclSXGOMbxniR8G1ifOCNUuiNUZRFG6DsbIqkJEBXSFFUxQpvtGkBaI5oF2u4oJ5Ed37thh_gOLJ1TKBaubGusv7vgUVoIk9A5F8H_HeX57zyRR2XU3czdSC4uZC_XpVwV7eT4-Z4bNooL0WJi1ZNx6ZFBC4qktNf7yifc7-iAEEDTWj3clwA81RJwAe9YbUMI3q640sNg8QlrZDiKFzuEuFocHces0bAYSyfLu5cwDw2wvJwQzYEMahjQ3V7RXpqg-YktsUoSTkLOHm7QNrM2Pko8ZAye58O-nTv1gD5yYDZ8st74x4MUHhNZhaR44byjw"
}
When I use this bearer token in the Authorization header an API call, I get the response:
{"Message":"Authorization has been denied for this request."}
I switched on diagnostic tracing and found this in the output:
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 2,
Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0xC78EFCC723A996C3351FB35793B4B1D7BC75BA97),
Clause[1] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
',
token: '{"typ":"JWT","alg":"RS256","x5t":"x478xyOplsM1H7NXk7Sx17x1upc","kid":"x478xyOplsM1H7NXk7Sx17x1upc"}.{"aud":"00000002-0000-0000-c000-000000000000","iss":"https://sts.windows.net/7b65d644-1434-41d4-a1a0-825ef80902d3/","iat":1513901664,"nbf":1513901664,"exp":1513905564,"aio":"Y2NgYPg7bbbRmu/aXjwejXZs73e5AgA=","appid":"6dfed4ed-56d9-4497-83ba-939bf4b78e25","appidacr":"1","idp":"https://sts.windows.net/7b65d644-1434-41d4-a1a0-825ef80902d3/","oid":"1a614c9c-4779-4697-98c4-99cee2ee5dcb","sub":"1a614c9c-4779-4697-98c4-99cee2ee5dcb","tenant_region_scope":"NA","tid":"7b65d644-1434-41d4-a1a0-825ef80902d3","uti":"5nMOpv6eok60JyzWwksuAA","ver":"1.0"}
RawData: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyIsImtpZCI6Ing0Nzh4eU9wbHNNMUg3TlhrN1N4MTd4MXVwYyJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMvIiwiaWF0IjoxNTEzOTAxNjY0LCJuYmYiOjE1MTM5MDE2NjQsImV4cCI6MTUxMzkwNTU2NCwiYWlvIjoiWTJOZ1lQZzdiYmJSbXUvYVhqd2VqWFpzNzNlNUFnQT0iLCJhcHBpZCI6IjZkZmVkNGVkLTU2ZDktNDQ5Ny04M2JhLTkzOWJmNGI3OGUyNSIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzdiNjVkNjQ0LTE0MzQtNDFkNC1hMWEwLTgyNWVmODA5MDJkMy8iLCJvaWQiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJzdWIiOiIxYTYxNGM5Yy00Nzc5LTQ2OTctOThjNC05OWNlZTJlZTVkY2IiLCJ0ZW5hbnRfcmVnaW9uX3Njb3BlIjoiTkEiLCJ0aWQiOiI3YjY1ZDY0NC0xNDM0LTQxZDQtYTFhMC04MjVlZjgwOTAyZDMiLCJ1dGkiOiI1bk1PcHY2ZW9rNjBKeXpXd2tzdUFBIiwidmVyIjoiMS4wIn0.mPzogfR2ndo89P-qWIypdPjrrBb0uEOO0Fo-H164C4Rm21zFQpkwVSFe-NP4MtvMnB5fJdhzGxzPDACFHBiQi7k7ZZVGv5bWaIbhGlPmKCQ1j6XaweYp7pm66R-RIsokZvR87nJ4ZkvYJIkuxnXPjChC-3FjsLDf43FKcByDPvvJKpVj48JW9N79vq77HQ2w8bnq172zOUflxGbuC2nDiwzkgWQiFboL-H3LLUxHqZHeE46u7pDSOrE3DSY1F5aPqBq1IDCg6ELcBcaLN27509oAH2rghkvXjHWOs9Nw3tszVoza7CpEGV7fjtSGN874GV_vx-ziqIOf1EgSBPEH6Q'.
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(String securityToken, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText)
at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
What am I missing?