Open Closed

Problem with custom login model in a tiered solution #4339


User avatar
0
jlavallet created
  • ABP Framework version: v 5.3.5

  • UI type MVC

  • DB provider: EF Core

  • Tiered (MVC) or Identity Server Separated (Angular): yes

  • Steps to reproduce the issue: I am replying to your message from a year ago because I have returned to this project and I’m still trying to work out the reason why I’m having trouble with the custom login solution. I have zipped up a project with two files added to the IdentityServer project. I believe the issue is that all the examples I have found are for the blended solution and not the tiered solution. Could you look at the attached – specifically the code in the AbpTest.IdentityServer’s Pages\Account folder that I added and suggest how to implement this for the tiered solution. AbpTest.zip

Thanks, From: ABP <noreply@abp.io>  Sent: Wednesday, February 16, 2022 6:42 PM Subject: Problem implementing Custom Login Model (#2572) Answered by maliming. — hi You can also send me your project and I'll download and check for issues. liming.ma@volosoft.com

You are receiving this because you are subscribed to this question. Do not reply to this email. Click here to view #2572 in browser.


22 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    did you send the project to @maliming

  • User Avatar
    0
    jlavallet created

    the link has been deleted by admin

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi jlavallet

    I will check your project.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    [ExposeServices(typeof(CustomLoginModel), typeof(IdentityServerSupportedLoginModel))]
    public class CustomLoginModel : IdentityServerSupportedLoginModel
    {
      private readonly ITenantRepository _tenantRepository;
    
    
      public CustomLoginModel(
        IAuthenticationSchemeProvider schemeProvider,
        IOptions<AbpAccountOptions> accountOptions,
        IAccountExternalProviderAppService accountExternalProviderAppService,
        IIdentityServerInteractionService interaction,
        IClientStore clientStore, IEventService identityServerEvents,
        ICurrentPrincipalAccessor currentPrincipalAccessor,
        IAbpRecaptchaValidatorFactory recaptchaValidatorFactory,
        IOptions<IdentityOptions> identityOptions,
        IOptionsSnapshot<reCAPTCHAOptions> reCaptchaOptions)
        : base(schemeProvider,
          accountOptions,
          accountExternalProviderAppService,
          interaction,
          clientStore,
          identityServerEvents,
          currentPrincipalAccessor,
          recaptchaValidatorFactory,
          identityOptions,
          reCaptchaOptions)
      {
      }
    }
    

  • User Avatar
    0
    jlavallet created

    Removing all my code and reverting it back to what it was is not the solution I was looking for. I am trying to implement a solution whereby the tenant entry is not necessary. If you looked at my code you would see that. Can you try again?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok

  • User Avatar
    0
    jlavallet created

    So I used the ExposeServices tweak to register the IdentityServerSupportedLoginModel, changed my class to inherit from it, and I switched back to the call to the base constructor for that base class. Everything works including my code down below.

    However, I can't understand why the Tenant selection is still showing. How do I hide that on the UI?

    
    [ExposeServices(typeof(CustomLoginModel), typeof(IdentityServerSupportedLoginModel))]
    public class CustomLoginModel : IdentityServerSupportedLoginModel
    {
      private readonly ITenantRepository _tenantRepository;
    
      public CustomLoginModel(
        IAuthenticationSchemeProvider schemeProvider,
        IOptions<AbpAccountOptions> accountOptions,
        IAccountExternalProviderAppService accountExternalProvider,
        IIdentityServerInteractionService interaction,
        IClientStore clientStore,
        IEventService identityServerEvents,
        ICurrentPrincipalAccessor currentPrincipalAccessor,
        IAbpRecaptchaValidatorFactory recaptchaValidatorFactory,
        IOptions<IdentityOptions> identityOptions,
        IOptionsSnapshot<reCAPTCHAOptions> reCaptchaOptions,
        ITenantRepository tenantRepository)
        : base(schemeProvider, accountOptions, accountExternalProvider, interaction, clientStore, identityServerEvents,
          currentPrincipalAccessor, recaptchaValidatorFactory, identityOptions, reCaptchaOptions)
      {
        _tenantRepository = tenantRepository;
      }
    
      public override async Task<IActionResult> OnPostAsync(string action)
      {
        var user = await FindUserAsync(LoginInput.UserNameOrEmailAddress);
        using (CurrentTenant.Change(user?.TenantId))
        {
          return await base.OnPostAsync(action);
        }
      }
    
      public override async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "",
        string returnUrlHash = "", string remoteError = null)
      {
        var user = await FindUserAsync(LoginInput.UserNameOrEmailAddress);
        using (CurrentTenant.Change(user?.TenantId))
        {
          return await base.OnGetExternalLoginCallbackAsync(returnUrl, returnUrlHash, remoteError);
        }
      }
    
      protected virtual async Task<IdentityUser> FindUserAsync(string uniqueUserNameOrEmailAddress)
      {
        IdentityUser user = null;
        using (CurrentTenant.Change(null))
        {
          user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
                 await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
    
          if (user != null)
          {
            return user;
          }
        }
    
        foreach (var tenant in await _tenantRepository.GetListAsync())
        {
          using (CurrentTenant.Change(tenant.Id))
          {
            user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
                   await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
    
            if (user != null)
            {
              return user;
            }
          }
        }
    
        return null;
      }
    }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    why the Tenant selection is still showing. How do I hide that on the UI?

    You need to customize the lepton-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Lepton/Themes/Lepton/Layouts/Account/Default.cshtml page.

  • User Avatar
    0
    jlavallet created

    Perfect. Thank you. Now I just have one more problem. I am getting the following error when I try to log out:

    Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'Volo.Abp.Account.Public.Web.Pages.Account.LogoutModel' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
       at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
       at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider.&lt;&gt;c__DisplayClass3_0.&lt;CreateModelFactory&gt;b__0(PageContext pageContext)
       at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.CreateInstance()
       at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeNextExceptionFilterAsync&gt;g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResourceFilter()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeAsync&gt;g__Logged|17_1(ResourceInvoker invoker)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeAsync&gt;g__Logged|17_1(ResourceInvoker invoker)
       at Microsoft.AspNetCore.Routing.EndpointMiddleware.&lt;Invoke&gt;g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
       at StackifyMiddleware.RequestTracerMiddleware.InvokeAsync(HttpContext context) in D:\a\1\s\StackifyMiddleware\RequestTracerMiddleware.cs:line 168
       at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.&lt;&gt;c__DisplayClass6_1.&lt;&lt;UseMiddlewareInterface&gt;b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
       at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
       at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.&lt;&gt;c__DisplayClass6_1.&lt;&lt;UseMiddlewareInterface&gt;b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.&lt;&gt;c__DisplayClass6_1.&lt;&lt;UseMiddlewareInterface&gt;b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.&lt;&gt;c__DisplayClass6_1.&lt;&lt;UseMiddlewareInterface&gt;b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    

    Do you have any idea what could be causing this?

    I am also getting a similar exception when I click the Login to this Tenant link on the SaaS\Tenants page.

    NOTE: These exceptions are coming from my original project and not the source code I sent to you.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The requested service 'Volo.Abp.Account.Public.Web.Pages.Account.LogoutModel' has not been registered.

    hi

    Do you have CustomLogoutModel class?

    If so please change the ExposeServices attribute just like CustomLoginModel.

    [ExposeServices(typeof(CustomLoginModel), typeof(IdentityServerSupportedLoginModel))]
    public class CustomLoginModel : IdentityServerSupportedLoginModel
    
  • User Avatar
    0
    jlavallet created

    Thanks for your help but that did not work. I am going to send you a zipped copy of my project. I think the problem has to do with the Web project.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

  • User Avatar
    0
    jlavallet created

    I added the typeof(LogoutModel) but as you can see in the screenshot that had no effect. I have done code comparisons between the working project I generated to isolate the custom login/logout model code and my existing project that I upgraded to v5.3.5 and I cannot see any differences that could account for the logout to fail under my existing project - but it does.

    In my screenshot above I also point out the URL above the stack trace. The port (44339) is that of the BlueSpot.Web project – not the BlueSpot.IdentityServerproject (44362).

    I mention the port because when I run the isolated solution, the logout works just fine, but I can tell that when I hover over the Logout menu item it is first navigating to the Web project at https://localhost:44339/Account/Logout and then something happens in the Volosoft code to redirect to the Identity Server.

    I believe the problem is something in my existing Web project. The redirection is just not happening - the Web project is not navigating that route because the Web project Account.LogoutModelis not registered.

    If you look at the code for the Web project, you can see that we have not overridden any Page\Account modules there:

    So maybe the real question is where is the Account.LogoutModel registered? How did it get "unregistered"?

    Can we WebEx?

  • User Avatar
    0
    jlavallet created

    Please see my post above before reading this post.

    Here is something else I have tried:

    As you can see from the screenshot above, I have:

    (1) created an Account folder underneath the Pages folder in the BlueSpot.Web project.

    (2) copied the abp-5.3.5\modules\account\src\Volo.Abp.Account.Web\Pages\Account\Logout.cshtml file to my new Account folder and have modified it to reference my CustomLogoutModel (below)

    (3) extended the Volo.Abp.Account.Public.Web.Pages.Account.LogoutModel into a CustomLogoutModel class and have overridden the OnGetAsync() method. I have copied the body of the original method into the new method.

    (4) run the application and attempted to log out - and…

    (5) gotten a NullReferenceException because the IdentitySecurityLogManager is null.

    What am I not understanding?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I will continue to test the project you sent me earlier

  • User Avatar
    0
    jlavallet created

    hi

    I will continue to test the project you sent me earlier

    Thank you. I'm getting a little heat from management that I have not solved this problem yet.

  • User Avatar
    1
    maliming created
    Support Team Fullstack Developer

    hi

    Please remove the <PackageReference Include="Volo.Abp.Account.Pro.Public.Web.IdentityServer" Version="5.3.5" /> from BlueSpot.Web

    I can log in and log out after that.

  • User Avatar
    0
    jlavallet created

    Thank you and I look forward to trying that out!

    However, right now I can't do anything and I'm waiting on licensing to write me back (see below). Can you do anything about this?

    Sent: Thursday, January 19, 2023 4:41 PM To: license@abp.io Subject: RE: License check failed?

    Just as a follow-up, and to send this message from the email address associated with our account, I wanted to let you know that the code is working on one of my developer’s machines, but not mine. It was working on my machine this morning before a reboot.

    I am getting the same licensing error when I try to run the application – which makes no sense because I thought the license is perpetual!

    2023-01-19 14:50:17.719 -06:00 [INF] - Volo.Abp.Swashbuckle.AbpSwashbuckleModule 2023-01-19 14:50:17.719 -06:00 [INF] - Volo.Abp.AspNetCore.Serilog.AbpAspNetCoreSerilogModule 2023-01-19 14:50:18.139 -06:00 [DBG] Started background worker: Volo.Abp.BackgroundJobs.BackgroundJobWorker 2023-01-19 14:50:18.152 -06:00 [DBG] Started background worker: Volo.Abp.IdentityServer.Tokens.TokenCleanupBackgroundWorker 2023-01-19 14:50:19.199 -06:00 [INF] User profile is available. Using 'C:\Users\jlavallet\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 2023-01-19 14:50:19.791 -06:00 [INF] Initialized all ABP modules. 2023-01-19 14:50:19.877 -06:00 [INF] Initializing UI Database 2023-01-19 14:50:20.385 -06:00 [ERR] ABP-LIC-0019 - License control code is not valid! 2023-01-19 14:50:20.401 -06:00 [ERR] ABP-LIC-ERROR - License check failed for 'Volo.Abp.LeptonTheme.Management.HttpApi-v5.3.5.0'.

    For more information, contact to license@abp.io.

    It fails when I run the DbMigrator as well.

    [16:35:11 INF] Started database migrations... [16:35:11 INF] Migrating schema for host database... [16:35:12 ERR] ABP-LIC-0019 - License control code is not valid! [16:35:12 ERR] ABP-LIC-ERROR - License check failed for 'Volo.CmsKit.Pro.Domain-v5.3.5.0'.

    For more information, contact to license@abp.io.

    D:\Century\Internal\BlueSpot\BlueSpotWorking\src\BlueSpot.DbMigrator\bin\Debug\net6.0\BlueSpot.DbMigrator.exe (process 11956) exited with code -42.

    Please advise. I’ve lost a whole day of development.

    Thanks, Jack

    Sent: Thursday, January 19, 2023 12:10 PM To: license@abp.io Subject: License check failed?

    I am getting a license check failed error message after a reboot. I have uninstalled and reinstalled the CLI and the Suite. Still have the same problem. Please advise.

    abp suite [12:02:26 INF] ABP CLI (https://abp.io) [12:02:27 INF] Version 5.3.5 (Stable) [12:02:27 WRN] ABP CLI has a newer stable version 7.0.1, please update to get the latest features and fixes. [12:02:27 WRN] [12:02:27 WRN] Update Command: [12:02:27 WRN] dotnet tool update -g Volo.Abp.Cli [12:02:27 WRN] Starting Suite v5.3.5 ... Opening http://localhost:3000 Press Ctrl+C to shut down. [12:02:36 ERR] ABP-LIC-0019 - License control code is not valid! [12:02:36 ERR] ABP-LIC-ERROR - License check failed for 'Volo.Abp.Suite-v5.3.5.0'.

    For more information, contact to license@abp.io.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can try logout and log in via CLI.

    or create a new pro project and copy the AbpLicenseCode to your project.

  • User Avatar
    0
    jlavallet created

    I tried both - Same result. I have even uninstalled and reinstalled the CLI and the Suite.No luck.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    We are working on ABP-LIC-0019.

  • User Avatar
    0
    jlavallet created

    Thank you! All is working now!

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19