title: How to use both Azure AD authentication and Identity on ASP.NET Core 3?
body: <p>The web application should allow internal employees with AD accounts to authenticate in the app using Azure AD Authentication. External users should be able to register and sign in using ASP.NET Core Identity. I can implement each one separately but not together in the same app. When I add both authentications to the same app, the ASP.NET Core Identity works perfectly. I can register and log in using Identity with no problem. However when I try to log in with Azure AD, the app redirects me to my tenant's login page, I submit a username and password, it redirects me back to the application but no user is authenticated. I hit the login button again and the same thing happens. It seems that the web app or browser is not saving the access token or something like that. </p>
  
  <p><strong>What am I doing wrong? Is it even possible to have two sets of authentication on the same app?</strong></p>
  
  <p>Thanks. Here's the code:</p>
  
  <h3>Packages</h3>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="3.1.1" /&gt;
  &lt;PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.1" /&gt;
  &lt;PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" /&gt;
  &lt;PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1"&gt;
  </code></pre>
  
  <h3>Startup Class</h3>
  
  <pre class="lang-cs prettyprint-override"><code>public IConfiguration Configuration { get; }
  
  public Startup(IConfiguration configuration) =&gt; Configuration = configuration;
  
  public void ConfigureServices(IServiceCollection services)
  {
      //  Add Azure AD authentication
      services.AddAuthentication(defaultScheme: AzureADDefaults.AuthenticationScheme)
          .AddAzureAD(options =&gt; Configuration.Bind("AzureAd", options));
  
      //  Add the application db context
      services.AddDbContext&lt;AppDbContext&gt;(options =&gt; options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  
      //  Add Identity using Entity Framework Core
      services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;()
          .AddEntityFrameworkStores&lt;AppDbContext&gt;()
          .AddDefaultTokenProviders();
  
      //  Configure Identity
      services.Configure&lt;IdentityOptions&gt;(options =&gt;
      {
          // Password settings.
          options.Password.RequireDigit = true;
          options.Password.RequireLowercase = true;
          options.Password.RequireNonAlphanumeric = true;
          options.Password.RequireUppercase = true;
          options.Password.RequiredLength = 6;
          options.Password.RequiredUniqueChars = 1;
  
          // Lockout settings.
          options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
          options.Lockout.MaxFailedAccessAttempts = 5;
          options.Lockout.AllowedForNewUsers = true;
  
          // User settings.
          options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
          options.User.RequireUniqueEmail = true;
      });
  
      services.AddMvc();
  }
  
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
      app.UseDeveloperExceptionPage();
      app.UseRouting();
      app.UseAuthentication();
      app.UseAuthorization();
      app.UseEndpoints(endpoints =&gt; endpoints.MapControllers());
  }
  </code></pre>
  
  <h3>User Controller</h3>
  
  <p>This is a custom controller where we handle HTTP requests related to authentication.</p>
  
  <pre class="lang-cs prettyprint-override"><code>private readonly UserManager&lt;ApplicationUser&gt; userManager;
  private readonly SignInManager&lt;ApplicationUser&gt; signInManager;
  
  public UserController(UserManager&lt;ApplicationUser&gt; um, SignInManager&lt;ApplicationUser&gt; sm) =&gt;
       (userManager, signInManager) = (um, sm);
  
  //  Internal employee users will authenticate using Azure AD
  [HttpGet("internal-signin")]
  public ChallengeResult InternalSignIn(string returnUrl = "/") =&gt; 
       Challenge(new AuthenticationProperties { RedirectUri = returnUrl }, AzureADDefaults.AuthenticationScheme);
  
  //  Display view with a form to create a new external user account
  [HttpGet("register")]
  public ViewResult Register() =&gt; View();
  
  //  Create a new account for an external user
  [HttpPost("register")]
  public async Task&lt;IActionResult&gt; Register(RegistrationInputModel inputModel)
  {
      //  Check if the model state is valid
      if (!ModelState.IsValid)
      {
          //  Redirect to the Register view
          return View(viewName: nameof(Register), model: inputModel);
      }
  
      //  Create an application user object
      ApplicationUser user = new ApplicationUser
      {
          //  Map the fields of the input model with the user
          UserName = inputModel.Email,
          Email = inputModel.Email,
          FirstName = inputModel.FirstName,
          LastName = inputModel.LastName,
          Company = inputModel.CompanyName,
      };
  
      //  Try to register the user on the database
      IdentityResult result = await userManager.CreateAsync(user, inputModel.Password);
  
      //  If failed, then set the error messages into the model state
      if (!result.Succeeded)
      {
          foreach (IdentityError error in result.Errors)
          {
              ModelState.AddModelError(string.Empty, error.Description);
          }
  
          //  Return the user to the registration view
          return View(viewName: nameof(Register), model: inputModel);
      }
  
      //  Sign In the user
      await signInManager.SignInAsync(user, isPersistent: false);
  
      //  Otherwise, redirect the user to the index page
      return RedirectToAction(nameof(HomeController.Index), controllerName: "Home");
  }
  
  //  External users sign out action
  [HttpGet("signout")]
  [Authorize]
  public async Task&lt;IActionResult&gt; SignOut()
  {
      await signInManager.SignOutAsync();
      return RedirectToAction(nameof(HomeController.Index), "Home");
  }
  
  //  Display form to login for external users
  [HttpGet("signin")]
  public ViewResult SignIn() =&gt; View();
  
  //  Login an external user
  [HttpPost("signin")]
  public async Task&lt;IActionResult&gt; SingIn(SingInInputModel inputModel)
  {
      //  Check if the model state is valid
      if (!ModelState.IsValid)
      {
          //  Send the user back to the sign in view
          return View(viewName: nameof(SignIn), model: inputModel);
      }
  
      //  Try to sign in the user
      SignInResult result = await signInManager
          .PasswordSignInAsync(inputModel.Email, inputModel.Password, inputModel.RememberMe, lockoutOnFailure: false);
  
      //  Check if the login was unsuccessful
      if (!result.Succeeded)
      {
          ModelState.AddModelError(string.Empty, "Invalid login attempt.");
          return View(viewName: nameof(SignIn), model: inputModel);
      }
  
      //  Send the user back to the index page
      return RedirectToAction(nameof(HomeController.Index), "Home");
  }
  </code></pre>
  
  <h3>Application User</h3>
  
  <pre class="lang-cs prettyprint-override"><code>public class ApplicationUser : Microsoft.AspNetCore.Identity.IdentityUser
  {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public string Company { get; set; }
  }
  </code></pre>