Activities of "anurag.tyagi"

Hi, please see the logs below:

20:03:07 [18:03:07 INF] Request finished HTTP/1.1 GET https://mybackend.com/api/saas/tenants/3a114414-b352-6751-1023-c40755a4a1bb/image - 500 null application/json; charset=utf-8 194.2802ms 20/06/2024
20:03:07 [18:03:07 INF] Request starting HTTP/1.1 GET http://mybackend.com/connect/authorize?response_type=code&client_id=Myapp_App&state=MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05%3B%252Ffree-inquiry&redirect_uri=https%3A%2F%2Fmyfrontend.com&scope=openid%20offline_access%20Myapp&code_challenge=0bxO4MWionxUKMExy-9tJkcC-sN8WJhDjQts2c6LHbo&code_challenge_method=S256&nonce=MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05&culture=en&ui-culture=en&returnUrl=%2Ffree-inquiry - null null 20/06/2024
20:03:07 [18:03:07 INF] The request URI matched a server endpoint: Authorization. 20/06/2024
20:03:07 [18:03:07 INF] The authorization request was successfully extracted: { 20/06/2024
20:03:07   "response_type": "code", 20/06/2024
20:03:07   "client_id": "Myapp_App", 20/06/2024
20:03:07   "state": "MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05;%2Ffree-inquiry", 20/06/2024
20:03:07   "redirect_uri": "https://myfrontend.com", 20/06/2024
20:03:07   "scope": "openid offline_access Myapp", 20/06/2024
20:03:07   "code_challenge": "0bxO4MWionxUKMExy-9tJkcC-sN8WJhDjQts2c6LHbo", 20/06/2024
20:03:07   "code_challenge_method": "S256", 20/06/2024
20:03:07   "nonce": "MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05", 20/06/2024
20:03:07   "culture": "en", 20/06/2024
20:03:07   "ui-culture": "en", 20/06/2024
20:03:07   "returnUrl": "/free-inquiry" 20/06/2024
20:03:07 }. 20/06/2024
20:03:08 [18:03:08 INF] Client validation failed because 'https://myfrontend.com' was not a valid redirect_uri for Myapp_App. 20/06/2024
20:03:08 [18:03:08 INF] The authorization request was rejected because the redirect_uri was invalid: 'https://myfrontend.com'. 20/06/2024
20:03:08 [18:03:08 INF] Request finished HTTP/1.1 GET https://mybackend.com/connect/authorize?response_type=code&client_id=Myapp_App&state=MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05%3B%252Ffree-inquiry&redirect_uri=https%3A%2F%2Fmyfrontend.com&scope=openid%20offline_access%20Myapp&code_challenge=0bxO4MWionxUKMExy-9tJkcC-sN8WJhDjQts2c6LHbo&code_challenge_method=S256&nonce=MFFzdn5-NENLRkFKTlZOLlZuRDhNVFdiUC4zVmRlMC1UX3RxV00zWkVvSk05&culture=en&ui-culture=en&returnUrl=%2Ffree-inquiry - 302 0 null 269.0968ms 20/06/2024

FYI, I have substituted the real domains with:

mybackend.com representing our backend domain myfrontend.com in place of the actual frontend domain

  • ABP Framework version: v8.1
  • UI Type: Angular
  • Database System: EF Core MySQL
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: NullInjectorError: NullInjectorError: No provider for InjectionToken CORE_OPTIONS!

Hi devs, I just updated our ABP commercial version from 8.0.4 to 8.1 and everything works fine except i get the following error in the frontend:

I also found this issue in other forum posts and tried the solutions there: https://support.abp.io/QA/Questions/5874/Upgrade-732-to-740-rc4-error I removed the cache and the node modules and reinstalled but the issue still remains.

here is my package.json, maybe there is a version mismatch somewhere: { "name": "GovernmentGpt", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve --open --host 0.0.0.0 --disable-host-check", "build": "ng build", "build:prod": "ng build --configuration production", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "ng lint" }, "private": true, "dependencies": { "@abp/ng.components": "~8.1.4", "@abp/ng.core": "~8.1.4", "@abp/ng.oauth": "~8.1.4", "@abp/ng.setting-management": "~8.1.4", "@abp/ng.theme.shared": "~8.1.4", "@angular/animations": "~17.0.0", "@angular/common": "~17.0.0", "@angular/compiler": "~17.0.0", "@angular/core": "~17.0.0", "@angular/forms": "~17.0.0", "@angular/localize": "~17.0.0", "@angular/platform-browser": "~17.0.0", "@angular/platform-browser-dynamic": "~17.0.0", "@angular/router": "~17.0.0", "@microsoft/signalr": "^8.0.0", "@volo/abp.commercial.ng.ui": "~8.1.4", "@volo/abp.ng.account": "~8.1.4", "@volo/abp.ng.audit-logging": "~8.1.4", "@volo/abp.ng.gdpr": "~8.1.4", "@volo/abp.ng.identity": "~8.1.4", "@volo/abp.ng.language-management": "~8.1.4", "@volo/abp.ng.openiddictpro": "~8.1.4", "@volo/abp.ng.saas": "~8.1.4", "@volo/abp.ng.text-template-management": "~8.1.4", "@volosoft/abp.ng.theme.lepton-x": "~3.0.2", "marked": "9.0.0", "ngx-markdown": "^17.1.1", "pdfmake": "^0.2.10", "primeicons": "^6.0.1", "primeng": "^17.4.0", "rxjs": "~7.8.1", "tslib": "^2.0.0", "zone.js": "~0.14.0" }, "devDependencies": { "@abp/ng.schematics": "~8.1.4", "@angular-devkit/build-angular": "~17.0.0", "@angular-eslint/builder": "~17.0.0", "@angular-eslint/eslint-plugin": "~17.0.0", "@angular-eslint/eslint-plugin-template": "~17.0.0", "@angular-eslint/schematics": "~17.0.0", "@angular-eslint/template-parser": "~17.0.0", "@angular/cli": "~17.0.0", "@angular/compiler-cli": "~17.0.0", "@angular/language-service": "~17.0.0", "@types/jasmine": "~3.6.0", "@types/node": "^12.0.0", "@typescript-eslint/eslint-plugin": "6.9.1", "@typescript-eslint/parser": "6.9.1", "eslint": "^8.0.0", "jasmine-core": "~4.0.0", "karma": "~6.3.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.1.0", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.0.0", "ng-packagr": "~17.0.0", "typescript": "~5.2.0" } } and here is my app.module.ts

`import { CoreModule } from '@abp/ng.core';
import { GdprConfigModule } from '@volo/abp.ng.gdpr/config';
import { SettingManagementConfigModule } from '@abp/ng.setting-management/config';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CommercialUiConfigModule } from '@volo/abp.commercial.ng.ui/config';
import { AccountAdminConfigModule } from '@volo/abp.ng.account/admin/config';
import { AccountPublicConfigModule } from '@volo/abp.ng.account/public/config';
import { AuditLoggingConfigModule } from '@volo/abp.ng.audit-logging/config';
import { IdentityConfigModule } from '@volo/abp.ng.identity/config';
import { LanguageManagementConfigModule } from '@volo/abp.ng.language-management/config';
import { registerLocale } from '@volo/abp.ng.language-management/locale';
import { SaasConfigModule } from '@volo/abp.ng.saas/config';
import { TextTemplateManagementConfigModule } from '@volo/abp.ng.text-template-management/config';
import { HttpErrorComponent, ThemeLeptonXModule } from '@volosoft/abp.ng.theme.lepton-x';
import { SideMenuLayoutModule } from '@volosoft/abp.ng.theme.lepton-x/layouts';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { APP_ROUTE_PROVIDER } from './route.provider';
import { OpeniddictproConfigModule } from '@volo/abp.ng.openiddictpro/config';
import { FeatureManagementModule } from '@abp/ng.feature-management';
import { AbpOAuthModule } from '@abp/ng.oauth';
import { AccountLayoutModule } from '@volosoft/abp.ng.theme.lepton-x/account';
import { ButtonModule } from 'primeng/button';
import { LpxBrandLogoModule, LpxIconModule, LpxNavbarModule } from '@volo/ngx-lepton-x.core';
import { PM_THEME_PROVIDER } from './theme/theme.provider';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AcceptLanguageInterceptor } from './language-interceptor/accept-language.interceptor';
import { CustomTenantModule } from './tenant/custom-tenant.module';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    ButtonModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    CoreModule.forRoot({
      environment,
      registerLocaleFn: registerLocale()
    }),
    AbpOAuthModule.forRoot(),
    ThemeSharedModule.forRoot({
      httpErrorConfig: {
        errorScreen: {
          component: HttpErrorComponent,
          forWhichErrors: [401, 403, 404, 500],
          hideCloseIcon: true
        }
      }
    }),
    AccountAdminConfigModule.forRoot(),
    AccountPublicConfigModule.forRoot(),
    IdentityConfigModule.forRoot(),
    LanguageManagementConfigModule.forRoot(),
    SaasConfigModule.forRoot(),
    AuditLoggingConfigModule.forRoot(),
    OpeniddictproConfigModule.forRoot(),
    TextTemplateManagementConfigModule.forRoot(),
    SettingManagementConfigModule.forRoot(),
    CommercialUiConfigModule.forRoot(),
    FeatureManagementModule.forRoot(),
    GdprConfigModule.forRoot({
      privacyPolicyUrl: 'gdpr-cookie-consent/privacy',
      cookiePolicyUrl: 'gdpr-cookie-consent/cookie'
    }),
    ThemeLeptonXModule.forRoot({}),
    SideMenuLayoutModule.forRoot(),
    AccountLayoutModule.forRoot(),
    LpxNavbarModule,
    LpxIconModule,
    LpxBrandLogoModule,
    CustomTenantModule
  ],
  providers: [
    APP_ROUTE_PROVIDER,
    PM_THEME_PROVIDER,
    {
      provide: HTTP_INTERCEPTORS,
      useExisting: AcceptLanguageInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
  exports: [
  ]
})
export class AppModule {}

any hints would be greatly appreciated!

best wishes

Hi,

Thanks for your reply.

I have already implemented the provided configuration in our project at the time of creating this ticket. However, this solution does not resolve the issue.

Could you please provide further assistance or an alternative approach to dynamically handle tenant-specific redirect URIs?

Thanks in advance

  • ABP Framework version: v8.0.2
  • UI Type: Angular
  • Database System: EF Core (MySQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: Redirect URI not matched to the allowed list
  • Steps to reproduce the issue:Enable multitenancy in abp using official documentation (https://docs.abp.io/en/abp/latest/Multi-Tenancy#domain-subdomain-tenant-resolver, https://github.com/abpframework/abp-samples/tree/master/DomainTenantResolver), create new tenant, try to login to the tenant using tenant URL.

I need assistance with an issue we're encountering with our ABP Commercial application configured for multitenancy (https://docs.abp.io/en/abp/1.0/Multi-Tenancy#domain-tenant-resolver). We have enabled multitenancy and are using OpenIddict for authentication. The configuration details for OpenIddict are stored in a database table named OpenIddictApplications, including the RedirectUris and PostLogoutRedirectUris columns.

Our application uses subdomain-based URLs for each tenant (e.g., tenant.mydomain.com). When creating a new tenant, the new tenant URL must be added to the list of allowed URIs in the RedirectUris and PostLogoutRedirectUris columns. However, this is not happening automatically, and we are facing a significant issue.

Redirect URI Mismatch Error: If the new tenant URL is not added to these lists, we receive an error indicating a mismatch of redirect URIs, preventing login and logout operations. No Support for Wildcards: The redirection endpoint URI must be an absolute URI as defined by [RFC3986] Section 4.3 (https://www.rfc-editor.org/rfc/rfc3986#section-4.3), and therefore we cannot use wildcard values like https://*.mydomain.com or https://{0}.mydomain.com. Given these constraints, we cannot dynamically handle new tenant URLs without manual updates to the allowed URIs lists.

Could you please guide how to resolve this issue? Specifically, we are looking for a solution that allows us to manage tenant-specific redirect URIs more dynamically without requiring manual updates to the database for each new tenant.

Any suggestions or best practices to handle this situation effectively would be greatly appreciated.

Hi,

Is it OK to disable the issuer validation on production?

also, without SetIssuer the login works just fine on all other tenants (tenant1.mydomain.com, tenant2.mydomain.com) but not for mydomain.com, it should work the same way for all URLs, right?

Can I somehow remove SetIssuer and find a solution to the problem described above? or the only way is to bring it back and disable issuer validation?

Many thanks for considering my request.

Hi,

Thanks for your response.

There are no backend logs on this issue, on the frontend console I see:

invalid issuer in discovery document expected: https://tenant.api.mydomain.com current: https://api.mydomain.com/

and when I check the https://api.mydomain.com/.well-known/openid-configuration endpoint, I see the following configuration:

{
  "issuer": "https://api.mydomain.com",
  "authorization_endpoint": "https://tenant.api.mydomain.com/connect/authorize",
  "token_endpoint": "https://tenant.api.mydomain.com/connect/token",
  "introspection_endpoint": "https://tenant.api.mydomain.com/connect/introspect",
  "end_session_endpoint": "https://tenant.api.mydomain.com/connect/logout"
}

FYI, this issue is not reproducible locally as soon as SetIssuer is in the if (!hostingEnvironment.IsDevelopment()) block.

  • ABP Framework version: v8.0.2
  • UI Type: Angular
  • Database System: EF Core (MySQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: infinite loop, with no errors in the logs
  • Steps to reproduce the issue: enable multitenancy, try to login as superadmin

I enabled multitenancy based on this example: ABP Framework Sample.

Later, I encountered an issue where the issuer endpoint was set to the main domain (mydomain.com) instead of the tenant subdomain (tenant.mydomain.com).

To resolve this, I had to comment out the following line in the configuration:

PreConfigure<OpenIddictServerBuilder>(builder =>
{
    builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment, configuration));
    builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment, configuration));
    // builder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
});

After commenting out this line, the multitenancy worked correctly for tenant1.mydomain.com, tenant2.mydomain.com, etc.

However, I now face an issue when trying to log in with the admin user to mydomain.com as a "superadmin". I end up in an infinite loop because the /connect/token endpoint responds with a 400 error:

{
  "error": "invalid_grant",
  "error_description": "The issuer associated to the specified token is not valid.",
  "error_uri": "https://documentation.openiddict.com/errors/ID2088"
}

In your forums, I found this topic: Local Docker Installation which suggests that the issue may be caused by the aforementioned commented-out line. However, my multitenancy setup does not work with that line included.

Additionally, there are no errors in the logs, and the logs are clean.

How can I fix this issue where the main domain login for the superadmin ends up in an infinite loop due to the invalid issuer token, while still maintaining the correct issuer endpoint for tenant subdomains?

Thank you.

Hi, thanks for the help. It got us quite far. I believe we only have one last issue before subdomains work for us:

we have a frontend angular method that establishes a connection to the backend but it reads the backend url from the appsettings and hence also contains the {0}, which is not resolved and not recognized by the backend.

private createConnection(): void {
    this.hubConnection = new HubConnectionBuilder()
      .withUrl(environment.apis.default.url + '/hubroute', { accessTokenFactory: () => localStorage.getItem('access_token') })
      .withAutomaticReconnect()
      .build();
  }

is there an out of the box way to get the resolved tenant url in the frontend?

  • ABP Framework version: v8.0.2
  • UI Type: Angular
  • Database System: EF Core (MySQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: Cannot add/remove values in data.user?.userActionGroups in the following toolbar. How to remove/add new values in the following setup? Could you please help with this situation? I am using Context Menu Component from LeptonX.
  • Steps to reproduce the issue: These are the files: Toolbar-container.component.html

<lpx-toolbar [profileRef]="profileRef$" (profileClick)="toggleCtxMenu()"> <ng-container *ngIf="{ user: userProfileService.user$ | async, profileRef: profileRef$ | async } as data" > <lpx-context-menu *ngIf="data.profileRef" #menu="lpx-context-menu" (lpxClickOutside)="menu.close()" [exceptedRefs]="[data.profileRef]" > <ng-container *ngFor="let actions of data.user?.userActionGroups;~~~~"> <lpx-context-menu-action-group> <lpx-navbar-routes [navbarItems]="actions" [routerItem]="false" ></lpx-navbar-routes> </lpx-context-menu-action-group> </ng-container> </lpx-context-menu> </ng-container> </lpx-toolbar>

Toolbar-container.component.ts

import { Component, ElementRef, ViewChild } from '@angular/core'; import { ReplaySubject } from 'rxjs'; import { ContextMenuComponent } from '@volosoft/ngx-lepton-x'; import { UserProfileService, ToolbarService } from '@volo/ngx-lepton-x.core'; import { ToolbarTranslateKeys } from './enums'; @Component({ selector: 'app-pm-toolbar-container', templateUrl: './toolbar-container.component.html', }) export class ToolbarContainerComponent { @ViewChild(ContextMenuComponent, { static: false }) ctxMenu!: ContextMenuComponent; profileRef$ = new ReplaySubject<ElementRef>(1); welcomeText = ToolbarTranslateKeys.ContextMenuWelcome; constructor( public toolbarService: ToolbarService, public userProfileService: UserProfileService ) {} toggleCtxMenu(): void { this.ctxMenu.toggle(); } }

toolbar-container.module.ts

import { ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LPX_TRANSLATE_TOKEN, LpxAvatarModule, LpxClickOutsideModule, LpxNavbarModule, LpxTranslateModule, } from '@volo/ngx-lepton-x.core'; import { LpxContextMenuModule } from '@volosoft/ngx-lepton-x'; import { LpxToolbarModule } from '@volosoft/ngx-lepton-x/layouts'; import { ToolbarContainerComponent } from './toolbar-container.component'; import { ToolbarTranslateDefaults } from './enums'; @NgModule({ declarations: [ToolbarContainerComponent], imports: [ CommonModule, LpxContextMenuModule, LpxClickOutsideModule, LpxAvatarModule, LpxNavbarModule, LpxToolbarModule, LpxTranslateModule, ], exports: [ToolbarContainerComponent], }) export class LpxToolbarContainerModule { static forRoot(): ModuleWithProviders<LpxToolbarContainerModule> { return { ngModule: LpxToolbarContainerModule, providers: [ { provide: LPX_TRANSLATE_TOKEN, useValue: [ToolbarTranslateDefaults], multi: true, }, ], }; } }

I added the code from that example to my project (v8.0.2) and deployed the version to an environment with an actual domain/subdomain, but it did not work. It has the issue that I described in the initial question.

can you maybe give some hints and ideas, on what could I check, and where I could have an issue?

Showing 11 to 20 of 28 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13