WIF10201: No valid key mapping found for securityToken: 'System.IdentityModel.Tokens.X509SecurityToken' and issuer: 'https://sts.windows.net/0f44c5d4-42b0-45c2-bf55-d0fea8430d33/'.
In my original blog post on enabling Azure Active Directory integration for an MVC application I realized that I left a few things out. I didn’t realize this though until one my customers started pulling their hair out because they couldn’t get it to work at all. After guiding them through the implementation they ran into the error in the title of this blog post. It turns out there were a number of things wrong and one thing I just couldn’t figure out because it wasn’t documented anywhere. And my first implementation avoided the problem altogether. This post will correct some holes so you can avoid this problem.
Problem 1: The TenantId
If this value is wrong, you’ll get the above error. So where do you get the tenantId from? I neglected to leave this out of my original post. So where does it come from and why did I leave it out of my original post? Let me reverse the questions. In my original post I created an application from scratch and enabled AAD integration which created a LocalDb with all of the data populated for me. That’s the easy way – what if you’re enabling an existing application (I did say I was going to get to that in a later post but I’ve been busy)? The TenantID can actually be found quite easily – you just have to know what to look for. In this case, the TenantID can be found by going to the Azure Portal (manage.windowsazure.com – this can’t be accessed from the Preview Portal just yet), clicking on the Active Directory link, clicking the directory that you are using (Default Directory in my case), clicking Applications and finally clicking the name of the application that you’ve integrated with AAD. Finally, at the bottom of the page click View Endpoints (on the icon bar at the bottom). That will display the dialog shown here:
In this dialog, focus on the WS-FEDERATION SIGN-ON ENDPOINT which looks like this in my case:
https://login.windows.net/67c3a3d5-b264-4328-ade6-7a7b81136117/wsfed
The guid in this string is the TenantID and this is what goes in the single row in the Tenants table in the database (refer to the original post).
That’s one problem taken care of.
Problem 2: The IssuingAuthorityKeys
This one was a little more interesting and I have to say it is one of those things that is just not documented well anywhere. I came across it in a forum post as I was researching the problem. The original forum post is here (but it leaves out a couple of steps): https://social.msdn.microsoft.com/Forums/en-US/8f2b7807-8d49-4190-978c-535c91f440c4/no-valid-key-mapping-found-for-securitytokensystemidentitymodeltokensx509securitytoken?forum=WindowsAzureAD. In this post there is a link to a documentation page here: https://msdn.microsoft.com/en-us/library/azure/dn641920.aspx. This documentation is excellent but without the forum post I never would have found it – and as I said it leaves out a couple of steps. However, I urge everyone to read it because it has topics that cover why you might get the above error even though the application worked previously. Another item to note is that the suggestions for automatically handling key rollover for VS 2013 applications don’t make sense – my application was created with VS 2013 and it didn’t get the rollover logic. Read the section on VS 2012 and update your application accordingly so this problem won’t happen in the future.
The key rollover problem occurs because Microsoft frequently creates new certificates to help mitigate any security issues and deal with the fact that certificates expire. But that leaves applications which depend on AAD integration in the lurch. So, how do you get the new key (or keys in this situation)? In the MSDN article referenced (in the section on manually updating your keys) above it tells you to navigate to the above dialog and copy the URL for the Federation Metadata Document and paste it into the address bar of your browser. It then tells you to find the x509Certificate element, copy the value of this element and save it as a .cer file (paste it into notepad and save the resulting file as key1.cer for example). After you do that you can double-click the file and view the details. On the Details tab it will give you the Thumbprint for the certificate and you’re good to go, right? Wrong – this is where the article gets it wrong. You need to do this for each certificate in the response. In this case there are now two keys that need to be entered into the IssuingAuthorityKeys table.
In Conclusion
One thing I haven’t figure out yet (more experimentation necessary) is that after making the changes to the code to automatically update the keys, it puts those thumbprints in the web.config file. I do not know if the database is needed at all after this. I will experiment some more and come back and update this post with additional information.
Hope this helps!