You Have to Sign Up With Your Own Multiple Organizations ASP.NET App Before You Can Sign In

Well, I’ve basically wrote most of the post already in the extra-long title! Smile

The ASP.NET project templates in VS2013 for multiple organizations apps contain a design choice which appears to be causing grief to many developers. In this post I am going to describe the issue (and show you how to make it a non-issue) – for the longer term I guess that the default behavior might have to be changed Smile

The Issue

The issue is easily explained. If you follow this blog, you already know that the ASP.NET project creation in VS2013 offers you the chance of configuring projects for various authentication styles for business apps.
One of the available templates generates one application meant to be consumed by multiple organizations: if you like buzzwords, that’s what you’d call a SaaS app or a multi-tenant app.

Those apps are meant to accept users from multiple organizations, and more precisely from multiple Windows Azure AD tenants. The template code contains logic for onboarding new organizations: it boils down to triggering the consent flow which allows a the admin of a prospective customer to instantly grant to the application access to his/her own tenant. The application template provides a database which is used to maintain the list of organizations that have been onboarded; such database is used at sign in time to establish if the incoming user belongs to one of the onboarded tenants. The template contains logic for processing messages about successful onboardings by adding the corresponding organization in the database.

image

Here there’s the thing that is causing the issue for some of you: at creation time, that database is empty.

Technically, when you create a multiple organizations app entry in Windows Azure AD you are doing two operations at once: creating the Application object which describes the app, and consenting for that app to use your directory (e.g. creating a service principal for it in your directory). For a deep dive on the application model, see here.
However, the VS template does NOT reflect the fact that your app is automatically provisioned in your own tenant. There is a reason for that: your application might call for some extra provisioning operations every time you onboard a new customer organization, and pre-provisioning a tenant in the DB would create an odd situation as your extra provisioning logic would have never a chance to run.

Regardless of the reason, this creates a problem for the ones among you who follow this rather natural sequence:

  • you create the app
  • you hit F5 right away
  • once presented with the home screen (shown below) you hit sign in and you enter the credentials of your user in your development tenant

image

  • after you entered your credentials, you are promptly welcomed by the error below

Server Error in ‘/’ Application.


WIF10201: No valid key mapping found for securityToken: ‘System.IdentityModel.Tokens.X509SecurityToken’ and issuer: ‘https://sts.windows.net/6133e43d-b70d-40ca-87c0-f16993f99070/’.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IdentityModel.Tokens.SecurityTokenValidationException: WIF10201: No valid key mapping found for securityToken: ‘System.IdentityModel.Tokens.X509SecurityToken’ and issuer: ‘https://sts.windows.net/6133e43d-b70d-40ca-87c0-f16993f99070/’.
Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[SecurityTokenValidationException: WIF10201: No valid key mapping found for securityToken: 'System.IdentityModel.Tokens.X509SecurityToken' and issuer: 'https://sts.windows.net/6133e43d-b70d-40ca-87c0-f16993f99070/'.]
   System.IdentityModel.Tokens.Saml2SecurityTokenHandler.ValidateToken(SecurityToken token) +867
   System.IdentityModel.Tokens.SecurityTokenHandlerCollection.ValidateToken(SecurityToken token) +73
   System.IdentityModel.Services.TokenReceiver.AuthenticateToken(SecurityToken token, Boolean ensureBearerToken, String endpointUri) +299
   System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request) +917
   System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +464
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.33440

That is basically telling you that your tenant has no entry in the local database, hence you are not supposed to access the application.

The Solution

The solution is super straightforward: you just need to use the template logic itself to sign up your own tenant. Click on the “Sign up for this application” link on the top bar. You’ll get to the following page:

image

Hit Sign Up. Authenticate as one admin of your development tenant. You’ll land on the following page:

image

Now, this would be a good place for warning you about a small issue… if you are on Windows 8.1 & IE11, chances are that hitting “grant access” will trigger the following JavaScript error:

image

The portal guys are going to fix this issue soon, but in the meanwhile you can work around this by adding this page in the Compatibility View list of IE11. Hit Alt+T, select Compatibility View Settings, and click the Add button to add windowsazure.com in the compatibility view list. The page will reload and you’ll be all set.

Hit “grant access”. You’ll be redirected back to your app:

image

That’s it. Your tenant is now in the DB and you can sign in:

image

 

All done. In just 3 clicks and one authentication you are all set.
Granted, the one among you stumbling on this would likely rather have the development tenant pre-populated by default in the database right out of the gate… my understanding is that this is pretty high in the list of things to change, but of course your feedback can help Smile

Leave a Reply

Your email address will not be published. Required fields are marked *