title: ASP.NET Identity executes database query on every page request when logged in
body: <p>I have noticed that my <code>ASP.NET</code> Web Forms application based on Identity <code>2.2.1</code> fetches logged in user data from the database on every page request. Is this normal and designed behaviour? For performance reasons, user data might be cached in Session. I have double checked if I have not added extra code in master page which might cause this behaviour. But no, I am using standard Web Form template with no code added to the master page.</p>
  
  <p>SQL statement executed on every page request:</p>
  
  <pre><code>SELECT 
  [Extent1].[Id] AS [Id], 
  [Extent1].[Email] AS [Email], 
  [Extent1].[EmailConfirmed] AS [EmailConfirmed], 
  [Extent1].[PasswordHash] AS [PasswordHash], 
  [Extent1].[SecurityStamp] AS [SecurityStamp], 
  [Extent1].[PhoneNumber] AS [PhoneNumber], 
  [Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed], 
  [Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled], 
  [Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc], 
  [Extent1].[LockoutEnabled] AS [LockoutEnabled], 
  [Extent1].[AccessFailedCount] AS [AccessFailedCount], 
  [Extent1].[UserName] AS [UserName]
  FROM [dbo].[AspNetUsers] AS [Extent1]
  WHERE [Extent1].[Id] = @p0
  </code></pre>
  
  <p>UPDATE 1</p>
  
  <p>As application works in Azure using App Service and Azure SQL, proof for database query behind each page request was Application Insights, as per attached screenshot.</p>
  
  <p><a href="https://i.stack.imgur.com/iA0Zm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/iA0Zm.png" alt="enter image description here"></a></p>
  
  <p>I have started to investigate further and have moved database to local environment. <code>SQL Server Profiler</code> shows there is in fact 10 queries to database on each page request. Those are SELECT to <code>AspNetUsers</code>, <code>AspNetUserClaims</code>, <code>AspNetUserLogins</code>, etc. Some of them are executed twice. This does not depend on master page. Pages not based on master page trigger same 10 queries as those based on one.</p>
  
  <p>I have done few modifications to default Visual Studio template, as per below source code. I have double checked that new project based on same template does not trigger any database queries once user is logged in.</p>
  
  <p>Modifications done:</p>
  
  <ul>
  <li>additional fields in <code>ApplicationUser</code> class, added to database table via migrations</li>
  <li>few configuration parameters</li>
  <li>email service configuration</li>
  </ul>
  
  <p>Source code:</p>
  
  <p>Global_asax</p>
  
  <pre><code>Public Class Global_asax
  Inherits HttpApplication
  
  Sub Application_Start(sender As Object, e As EventArgs)
      ' Fires when the application is started
      RouteConfig.RegisterRoutes(RouteTable.Routes)
      BundleConfig.RegisterBundles(BundleTable.Bundles)
  End Sub
  End Class
  </code></pre>
  
  <p>Startup</p>
  
  <pre><code>Partial Public Class Startup
  
  ' For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301883
  Public Sub ConfigureAuth(app As IAppBuilder)
      'Configure the db context, user manager and signin manager to use a single instance per request
      app.CreatePerOwinContext(AddressOf ApplicationDbContext.Create)
      app.CreatePerOwinContext(Of ApplicationUserManager)(AddressOf ApplicationUserManager.Create)
      app.CreatePerOwinContext(Of ApplicationSignInManager)(AddressOf ApplicationSignInManager.Create)
  
      ' Enable the application to use a cookie to store information for the signed in user
      app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
          .AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
          .Provider = New CookieAuthenticationProvider() With {
              .OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(Of ApplicationUserManager, ApplicationUser)(
                  validateInterval:=TimeSpan.FromMinutes(0),
                  regenerateIdentity:=Function(manager, user) user.GenerateUserIdentityAsync(manager))},
          .LoginPath = New PathString("/Account/Login"),
          .ExpireTimeSpan = TimeSpan.FromMinutes(20),
          .SlidingExpiration = True})
  
      ' Use a cookie to temporarily store information about a user logging in with a third party login provider
      'app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie)
  
      ' Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
      'app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5))
  
      ' Enables the application to remember the second login verification factor such as phone or email.
      ' Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
      ' This is similar to the RememberMe option when you log in.
      'app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)
  
      ' Uncomment the following lines to enable logging in with third party login providers
      'app.UseMicrosoftAccountAuthentication(
      '    clientId:= "",
      '    clientSecret:= "")
  
      'app.UseTwitterAuthentication(
      '   consumerKey:= "",
      '   consumerSecret:= "")
  
      'app.UseFacebookAuthentication(
      '   appId:= "",
      '   appSecret:= "")
  
      'app.UseGoogleAuthentication(New GoogleOAuth2AuthenticationOptions() With {
      '   .ClientId = "",
      '   .ClientSecret = ""})
  End Sub
  End Class
  </code></pre>
  
  <p>IdentityConfig.vb</p>
  
  <pre><code>Public Class EmailService
  Implements IIdentityMessageService
  Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync
      ' Plug in your email service here to send an email.
      'Return Task.FromResult(0)
      Dim client As New Net.Mail.SmtpClient(DTAppSettings.SendGrid_SMTPServer, 587)
      Dim credentials As New Net.NetworkCredential(DTAppSettings.SendGrid_Username, DTAppSettings.SendGrid_Password)
      client.Credentials = credentials
      client.EnableSsl = True
      Dim mailmessage As New Net.Mail.MailMessage With {
          .From = New Net.Mail.MailAddress(DTAppSettings.SendGrid_FromAddress, DTAppSettings.SendGrid_FromName),
          .Subject = message.Subject,
          .Body = message.Body,
          .IsBodyHtml = True
      }
      mailmessage.To.Add(message.Destination)
      Return client.SendMailAsync(mailmessage)
  End Function
  End Class
  
  Public Class SmsService
  Implements IIdentityMessageService
  Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync
      ' Plug in your SMS service here to send a text message.
      Return Task.FromResult(0)
  End Function
  End Class
  
  ' Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
  Public Class ApplicationUserManager
  Inherits UserManager(Of ApplicationUser)
  Public Sub New(store As IUserStore(Of ApplicationUser))
      MyBase.New(store)
  End Sub
  
  Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationUserManager), context As IOwinContext) As ApplicationUserManager
      Dim manager = New ApplicationUserManager(New UserStore(Of ApplicationUser)(context.[Get](Of ApplicationDbContext)()))
      ' Configure validation logic for usernames
      manager.UserValidator = New UserValidator(Of ApplicationUser)(manager) With {
        .AllowOnlyAlphanumericUserNames = False,
        .RequireUniqueEmail = True
      }
  
      ' Configure validation logic for passwords
      manager.PasswordValidator = New PasswordValidator() With {
        .RequiredLength = 6,
        .RequireNonLetterOrDigit = True,
        .RequireDigit = True,
        .RequireLowercase = True,
        .RequireUppercase = True
      }
      ' Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user. 
      ' You can write your own provider and plug in here.
      'manager.RegisterTwoFactorProvider("Phone Code", New PhoneNumberTokenProvider(Of ApplicationUser)() With {
      '  .MessageFormat = "Your security code is {0}"
      '})
      'manager.RegisterTwoFactorProvider("Email Code", New EmailTokenProvider(Of ApplicationUser)() With {
      '  .Subject = "Security Code",
      '  .BodyFormat = "Your security code is {0}"
      '})
  
      ' Configure user lockout defaults
      manager.UserLockoutEnabledByDefault = True
      manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5)
      manager.MaxFailedAccessAttemptsBeforeLockout = 5
  
      manager.EmailService = New EmailService()
      manager.SmsService = New SmsService()
      Dim dataProtectionProvider = options.DataProtectionProvider
      If dataProtectionProvider IsNot Nothing Then
          manager.UserTokenProvider = New DataProtectorTokenProvider(Of ApplicationUser)(dataProtectionProvider.Create("ASP.NET Identity")) With {
              .TokenLifespan = TimeSpan.FromHours(1)
              }
      End If
      Return manager
  End Function
  End Class
  
  Public Class ApplicationSignInManager
  Inherits SignInManager(Of ApplicationUser, String)
  Public Sub New(userManager As ApplicationUserManager, authenticationManager As IAuthenticationManager)
      MyBase.New(userManager, authenticationManager)
  End Sub
  
  Public Overrides Function CreateUserIdentityAsync(user As ApplicationUser) As Task(Of ClaimsIdentity)
      Return user.GenerateUserIdentityAsync(DirectCast(UserManager, ApplicationUserManager))
  End Function
  
  Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationSignInManager), context As IOwinContext) As ApplicationSignInManager
      Return New ApplicationSignInManager(context.GetUserManager(Of ApplicationUserManager)(), context.Authentication)
  End Function
  End Class
  </code></pre>