title: ASP.NET MVC Identity - Using internal User and Azure AD Authentication together
body: <p>We are already running an ASP.NET MVC web application which is using internal users via token authentication. This is implemented in the standard way the ASP.NET MVC template provides.</p>
  <p>Now we have a requirement to extend this authentication model and allow external Azure AD users to sign into the web application for configured tenant. I have figured out everything on the Azure AD side. Thanks to Microsoft's <a href="https://github.com/Azure-Samples/active-directory-dotnet-webapp-multitenant-openidconnect" rel="nofollow noreferrer">Azure Samples</a> example.</p>
  <p>Now both <em>individual account authentication</em> and <em>Azure AD</em> are working well independently. But they're not working together. When I insert both middleware together its giving issue.</p>
  <p>Here's my startup_auth.cs file:</p>
  <pre><code>public partial class Startup
  {
      
      public void ConfigureAuth(IAppBuilder app)
      {
          app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
          
          app.CreatePerOwinContext(ApplicationDbContext.Create);
          app.CreatePerOwinContext&lt;ApplicationUserManager&gt;(ApplicationUserManager.Create);
          app.CreatePerOwinContext&lt;ApplicationSignInManager&gt;(ApplicationSignInManager.Create);
  
  
          app.UseCookieAuthentication(new CookieAuthenticationOptions
          {
              AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
              LoginPath = new PathString(&quot;/Account/Login&quot;),
              Provider = new CookieAuthenticationProvider
              {
                  OnValidateIdentity = SecurityStampValidator.OnValidateIdentity&lt;ApplicationUserManager, ApplicationUser&gt;(
                      validateInterval: TimeSpan.FromMinutes(30),
                      regenerateIdentity: (manager, user) =&gt; user.GenerateUserIdentityAsync(manager))
              }
          });            
          app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
  
  
          string ClientId = ConfigurationManager.AppSettings[&quot;ida:ClientID&quot;];            
          string Authority = &quot;https://login.microsoftonline.com/common/&quot;;
  
      app.UseOpenIdConnectAuthentication(
          new OpenIdConnectAuthenticationOptions
          {
              ClientId = ClientId,
              Authority = Authority,
              TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
              {                        
                  ValidateIssuer = false,
              },
              Notifications = new OpenIdConnectAuthenticationNotifications()
              {
                  RedirectToIdentityProvider = (context) =&gt;
                  {                            
                      string appBaseUrl = context.Request.Scheme + &quot;://&quot; + context.Request.Host + context.Request.PathBase;                         
                      context.ProtocolMessage.RedirectUri = appBaseUrl;
                      context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                      return Task.FromResult(0);
                  },                        
                  SecurityTokenValidated = (context) =&gt;
                  {
                      // retriever caller data from the incoming principal
                      string issuer = context.AuthenticationTicket.Identity.FindFirst(&quot;iss&quot;).Value;
                      string UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
                      string tenantID = context.AuthenticationTicket.Identity.FindFirst(&quot;http://schemas.microsoft.com/identity/claims/tenantid&quot;).Value;
  
                      if (
                          // the caller comes from an admin-consented, recorded issuer
                          (db.Tenants.FirstOrDefault(a =&gt; ((a.IssValue == issuer) &amp;&amp; (a.AdminConsented))) == null)
                          // the caller is recorded in the db of users who went through the individual onboardoing
                          &amp;&amp; (db.Users.FirstOrDefault(b =&gt;((b.UPN == UPN) &amp;&amp; (b.TenantID == tenantID))) == null)
                          )
                          // the caller was neither from a trusted issuer or a registered user - throw to block the authentication flow
                          throw new SecurityTokenValidationException();                            
                      return Task.FromResult(0);
                  },
                  AuthenticationFailed = (context) =&gt;
                  {
                      context.OwinContext.Response.Redirect(&quot;/Home/Error?message=&quot; + context.Exception.Message);
                      context.HandleResponse(); // Suppress the exception
                      return Task.FromResult(0);
                  }
              }
          });
  
      }
  }
  </code></pre>
  <p>This configuration works well for local user accounts but doesn't work for AAD. To enable AAD authentication, I need to configure the <code>UseCookieAuthentication</code> part as shown below, which will break my local user account authentication.</p>
  <pre><code>app.UseCookieAuthentication(new CookieAuthenticationOptions { });
  </code></pre>
  <p>Basically I need to remove the local users middleware to get AAD work.</p>
  <p>What I mean by AAD not working is, I am not able to go to any secured action which is protected by the <code>[Authorize]</code> attribute. It's calling the <code>SecurityTokenValidated</code> event, and I am able to get all AAD claims and able to validate against my custom tenant. But when I redirect to root of my app (which is a secured action) at the end, it throws me back to my custom login page. Seems it's not internally signing in the user and not creating the necessary authentication cookies.</p>
  <p>I would appreciate any ideas on what I could be missing here.</p>
  <p>Thanks</p>