(CORE) CORE (2022)

How to integrated MS DefaulUI with CustomUserStore

This long way started from my database, I have very simple database in MySQL and don't want follow idiotic Microsoft rules to implement Microsoft story. Microsoft way is most idiotic way as possible in any case:



But I want to use in my project standard View and algorithm from hidden area Identity. With my own database in MySQL server!



What child hired from Microsoft propose for public?


So, we need realize UserManager and SignManager without idiotic template EF Code first, without deploying from code to DB (we going from existing DB to code), with free MySQL server without proprietary MsSQL. We don't use C# in project code, we don't use idiotic MS template with mix code and View in one project. And we don't use idiotic MS Database structure needed to UserManager and SignManager.



This allow me embed standard Login/Registration logic to my project.



So, firstly we need to configure Net core services.



But firstly look details to project explorer.

So, this is DI-container configuration of main project FrontEndCode.


   1:  Imports BackendAPI
   2:  Imports BackendAPI.Model
   3:  Imports BackendAPI.Notification
   4:  Imports BackendAPI.Services
   5:  Imports FrontEnd.Data
   6:  Imports FrontEndData
   7:  Imports FrontEndData.Models
   8:  Imports Microsoft.AspNetCore.Authentication.Cookies
   9:  Imports Microsoft.AspNetCore.Builder
  10:  Imports Microsoft.AspNetCore.Hosting
  11:  Imports Microsoft.AspNetCore.Http
  12:  Imports Microsoft.AspNetCore.Http.Connections
  13:  Imports Microsoft.AspNetCore.HttpOverrides
  14:  Imports Microsoft.AspNetCore.Identity
  15:  Imports Microsoft.AspNetCore.Mvc.ApplicationModels
  16:  Imports Microsoft.AspNetCore.Mvc.RazorPages
  17:  Imports Microsoft.AspNetCore.Routing
  18:  Imports Microsoft.EntityFrameworkCore
  19:  Imports Microsoft.Extensions.Configuration
  20:  Imports Microsoft.Extensions.DependencyInjection
  21:  Imports Microsoft.Extensions.FileProviders
  22:  Imports Microsoft.Extensions.Hosting
  23:  Imports Microsoft.Extensions.Logging
  24:  Imports Microsoft.OpenApi.Models
  25:  Imports System.Diagnostics
  26:  Imports Microsoft.AspNetCore.Mvc
  27:  Imports Microsoft.AspNetCore
  28:  Imports Microsoft.Extensions.Options
  29:  Imports Newtonsoft.Json
  30:  Imports BackendAPI.FrontEndModels
  31:  Imports Microsoft.AspNetCore.Mvc.Infrastructure
  32:  Imports Microsoft.AspNetCore.StaticFiles
  33:   
  34:  Module Program
  35:   
  36:      Public Property Environment As IWebHostEnvironment
  37:      Public Property LoggerFactory As ILoggerFactory
  38:      Public Property Configuration As IConfiguration
  39:      Sub Main(Args() As String)
  40:          Dim Builder = WebApplication.CreateBuilder(Args)
  41:          'Add services to the container.
  42:          Debug.WriteLine($"ContentRootPath: {Builder.Environment.ContentRootPath}, WebRootPath: {Builder.Environment.WebRootPath}, StaticFilesRoot: {Builder.Configuration("StaticFilesRoot")}, RazorPagesRoot: ?,  WebRootFileProvider: {Builder.Environment.WebRootFileProvider}, IsDevelopment: {Builder.Environment.IsDevelopment} ")
  43:   
  44:          Builder.Host.ConfigureLogging(Sub(hostingContext, logging)
  45:                                            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"))
  46:                                            logging.AddConsole
  47:                                            logging.AddDebug
  48:                                            'logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug)
  49:                                            logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug)
  50:                                        End Sub)
  51:   
  52:          Builder.WebHost.ConfigureKestrel(Sub(KestrelServerOptions)
  53:                                               KestrelServerOptions.ListenLocalhost(5158)
  54:                                               KestrelServerOptions.ListenAnyIP(7168, Function(X) X.UseHttps)
  55:                                           End Sub)
  56:          Environment = Builder.Environment
  57:          Configuration = Builder.Configuration
  58:   
  59:          Builder.Services.AddHttpContextAccessor
  60:          Builder.Services.AddSingleton(Of IActionContextAccessor, ActionContextAccessor)
  61:   
  62:          'The call to AddMvc also calls AddRazorPages internally
  63:          Builder.Services.AddMvcCore(Sub(MvcOptions) MvcOptions.EnableEndpointRouting = False)
  64:   
  65:          Dim AES As New AesCryptor
  66:   
  67:          Builder.Services.AddDbContext(Of ApplicationDbContext)(Function(ByVal options As DbContextOptionsBuilder)
  68:                                                                     Return options.UseMySql(AES.DecryptSqlConnection(Builder.Configuration.GetConnectionString("DefaultConnection"), "XXXXXXXXXXXXXXXXX"),
  69:                                                              ServerVersion.Parse("10.5.9-MariaDB-1:10.5.9+maria~xenial"), 'SHOW VARIABLES LIKE "%version%";
  70:                                                              Sub(ByVal mySqlOption As Microsoft.EntityFrameworkCore.Infrastructure.MySqlDbContextOptionsBuilder)
  71:                                                                  mySqlOption.CommandTimeout(10)
  72:                                                                  mySqlOption.EnableRetryOnFailure(10)
  73:                                                              End Sub)
  74:                                                                 End Function, ServiceLifetime.Transient, ServiceLifetime.Transient)
  75:   
  76:          ' configure strongly typed settings object
  77:          Builder.Services.Configure(Of Jwt.JwtSettings)(Builder.Configuration.GetSection("JwtSetting"))
  78:   
  79:          'configure DI for application services
  80:          Builder.Services.AddScoped(Of IUserService, UserService)
  81:          Builder.Services.AddSingleton(Of IAesCryptor, AesCryptor)
  82:          'Builder.Services.AddSingleton(Of INotificationCacheService, NotificationCacheService)
  83:   
  84:          Builder.Services.AddDatabaseDeveloperPageExceptionFilter
  85:   
  86:          Builder.Services.AddIdentity(Of ApplicationUser, ApplcationRole).AddDefaultUI().AddDefaultTokenProviders().AddUserStore(Of CustomUserStore).AddRoleStore(Of CustomRoleStore)()
  87:   
  88:       
  89:          Builder.Services.Configure(Of IdentityOptions)(Sub(options)
  90:                                                             options.SignIn.RequireConfirmedPhoneNumber = False
  91:                                                             options.SignIn.RequireConfirmedEmail = False
  92:                                                             options.SignIn.RequireConfirmedAccount = False
  93:                                                             ''Password settings.
  94:                                                             'options.Password.RequireDigit = True
  95:                                                             'options.Password.RequireLowercase = True
  96:                                                             'options.Password.RequireNonAlphanumeric = True
  97:                                                             'options.Password.RequireUppercase = True
  98:                                                             'options.Password.RequiredLength = 6
  99:                                                             'options.Password.RequiredUniqueChars = 1
 100:                                                             ''Lockout settings.
 101:                                                             'options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5)
 102:                                                             'options.Lockout.MaxFailedAccessAttempts = 5
 103:                                                             'options.Lockout.AllowedForNewUsers = True
 104:                                                             ''User settings.
 105:                                                             'options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"
 106:                                                             'options.User.RequireUniqueEmail = False
 107:                                                         End Sub)
 108:   
 109:          ' ******* Configure the HTTP request pipeline. *******
 110:          Dim App = Builder.Build
 111:   
 112:          Dim I As Integer = 0
 113:          Builder.Services.OrderBy(Function(Z) Z.Lifetime.ToString).ThenBy(Function(Z) Z.ServiceType.ToString).Distinct.ToList.ForEach(Sub(X)
 114:                                                                                                                                           I = I + 1
 115:                                                                                                                                           Dim ST As Type = X.ImplementationType
 116:                                                                                                                                           If ST IsNot Nothing Then
 117:                                                                                                                                               Dim ServiceInstance = Nothing
 118:                                                                                                                                               Try
 119:                                                                                                                                                   ServiceInstance = App.Services.GetRequiredService(ST)
 120:                                                                                                                                               Catch ex As System.InvalidOperationException
 121:                                                                                                                                               End Try
 122:                                                                                                                                               Debug.WriteLine($"{I}. {X.Lifetime} : {IIf(ServiceInstance IsNot Nothing, "HasInstance", "           ")} : {X.ServiceType}")
 123:                                                                                                                                           End If
 124:                                                                                                                                       End Sub)
 125:          'Scoped    : one instance per web request
 126:          'Transient : each time the service is requested, a new instance is created
 127:   
 128:          LoggerFactory = App.Services.GetRequiredService(Of ILoggerFactory)
 129:   
 130:          If App.Environment.IsDevelopment Then
 131:              'The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 132:          Else
 133:              App.UseExceptionHandler("/Home/Error")
 134:              App.UseHsts 'HTTPS Redirection Middleware (UseHttpsRedirection) to redirect HTTP requests to HTTPS. HSTS Middleware (UseHsts) to send HTTP Strict Transport Security Protocol (HSTS) headers to clients.
 135:          End If
 136:   
 137:          App.UseForwardedHeaders(New ForwardedHeadersOptions With {
 138:              .ForwardedHeaders = ForwardedHeaders.XForwardedFor Or ForwardedHeaders.XForwardedProto
 139:              })
 140:   
 141:          If Builder.Environment.IsDevelopment Then App.UseDeveloperExceptionPage
 142:   
 143:          App.UseRouting
 144:   
 145:          '--- from Identity project
 146:          App.UseHttpsRedirection
 147:          App.UseStaticFiles(New StaticFileOptions With {.FileProvider = New PhysicalFileProvider(Builder.Configuration("StaticFilesRoot"))})
 148:          App.UseStaticFiles(New StaticFileOptions With {.FileProvider = New PhysicalFileProvider(Builder.Configuration("StaticFilesRoot")), .RequestPath = "/Identity"})
 149:          App.UseAuthentication
 150:          App.UseAuthorization
 151:          App.MapControllerRoute(name:="areas", pattern:="{area:exists}/{controller=Account}/{action=Index}/{id?}")
 152:          App.MapControllerRoute(name:="default", pattern:="{controller=Home}/{action=Index}/{id?}")
 153:   
 154:          App.MapRazorPages
 155:          '----------------------
 156:   
 157:          'Route anylizer
 158:          App.Use(Async Function(context As HttpContext, NextRequestDelegate As RequestDelegate)
 159:                      Dim CurrentEndpoint = context.GetEndpoint()
 160:                      If (CurrentEndpoint Is Nothing) Then
 161:                          Debug.WriteLine($"RequestPath {context.Request.Path} endpoint nothing.")
 162:                          Dim StaticOptions As StaticFileOptions = New StaticFileOptions With {.FileProvider = New PhysicalFileProvider(Builder.Configuration("StaticFilesRoot"))}
 163:                          Dim Opt As IOptions(Of StaticFileOptions) = Options.Create(StaticOptions)
 164:                          Dim NewEnvironment As IWebHostEnvironment = Environment
 165:                          NewEnvironment.ContentRootPath = Builder.Configuration("StaticFilesRoot")
 166:                          NewEnvironment.WebRootPath = Builder.Configuration("StaticFilesRoot")
 167:                          Dim StaticMiddleware = New StaticFileMiddleware(
 168:                              Async Function()
 169:                                  'Await NextRequestDelegate(context)
 170:                                  Dim StaticFile As IFileInfo = Opt.Value.FileProvider.GetFileInfo(context.Request.Path)
 171:                                  If Not StaticFile.Exists Then
 172:                                      Await context.Response.WriteAsync("File is missing")
 173:                                  Else
 174:                                      Await context.Response.SendFileAsync(StaticFile)
 175:                                  End If
 176:   
 177:                              End Function,
 178:                              NewEnvironment,
 179:                              Opt,
 180:                              LoggerFactory)
 181:                          Await StaticMiddleware.Invoke(context)
 182:                      Else
 183:                          Debug.WriteLine($"Endpoint: {CurrentEndpoint.DisplayName}")
 184:                          Dim Endpoint As RouteEndpoint = TryCast(CurrentEndpoint, RouteEndpoint)
 185:                          Debug.WriteLine($"RoutePattern: {Endpoint?.RoutePattern.RawText}")
 186:                          For j As Integer = 0 To CurrentEndpoint.Metadata.Count - 1
 187:                              Debug.WriteLine($"Endpoint Metadata {j}: {CurrentEndpoint.Metadata(j)}")
 188:                          Next
 189:                          Await NextRequestDelegate(context)
 190:                      End If
 191:                  End Function)
 192:   
 193:          App.UseEndpoints(Function(x) x.MapControllers)
 194:   
 195:          App.Run()
 196:      End Sub
 197:  End Module

Project has only one controller needed to work - HomeController. It call View with SignManager and UserManager.



UserController not needed in this workflow, because UserController working from Hidden MS Identity area. But we can doing something in this area, of course need firstly inject UserManager or SignManager to this controller.



In this workflow - login/logout/register is enough view logic only. Also in my case I need to change root tag for body content.



And main parts of this puzzle - CustomUserStore and CustomRoleStore I have uploaded to GitHub https://github.com/Alex-1557/CustomIdentityInsteadDefaultIdentity.





Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: http://www.vb-net.com/CustomIdentityProvider/Index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>