Hello,
We have reviewed and re-tested this scenario, and this is something we have also discussed and experimented with in the past.
In short, the described setup is not a supported authentication flow in ABP Angular.
ABP Angular establishes its authentication and UI state during the application bootstrap phase, which relies on:
/api/abp/application-configuration)When using loginUsingGrant for programmatic login:
However, since the Angular application is already bootstrapped in an anonymous state, the following are not re-initialized:
In iframe-based scenarios specifically:
Supported and recommended approaches are:
Because of these reasons, the missing menus and UI state are not a bug, but a known architectural limitation of this setup.
Thank you for your understanding.
Hi,
Thank you for reaching out. This is a known behavior when using loginUsingGrant instead of the standard redirect-based login flow.
When using standard redirect login, the entire application reloads, which triggers APP_INITIALIZERs to run again. This refreshes:
However, when using loginUsingGrant:
APP_INITIALIZERs don't re-executeAfter a successful loginUsingGrant, you need to manually refresh the application state by calling refreshAppState():
import { ConfigStateService, AbpOAuthService } from '@abp/ng.core';
import { firstValueFrom } from 'rxjs';
@Component({...})
export class YourLoginComponent {
private oAuthService = inject(AbpOAuthService);
private configStateService = inject(ConfigStateService);
async performLogin(username: string, password: string) {
// 1. Perform programmatic login
await this.oAuthService.loginUsingGrant('password', {
username,
password,
scope: 'openid profile offline_access AeroMiles'
});
// 2. Refresh ConfigState to update permissions and trigger menu visibility
await firstValueFrom(this.configStateService.refreshAppState());
// 3. Optional: Navigate to a route
// this.router.navigate(['/']);
}
}
| Scenario | APP_INITIALIZER | ConfigState | Menus |
|----------|-----------------|-------------|-------|
| Redirect Login | ✅ Runs | ✅ Updated | ✅ Visible |
| loginUsingGrant only | ❌ Doesn't run | ❌ Stale | ❌ Not visible |
| loginUsingGrant + refreshAppState() | ❌ Doesn't run | ✅ Updated | ✅ Visible |
The refreshAppState() method fetches the latest application configuration from the server, including the current user's permissions. This update triggers the permission-based visibility checks on menu items, making them appear correctly.
ABP Version: This solution applies to ABP 7.0+. If you're using an older version, please let us know.
Alternative approach: If refreshAppState() doesn't work in your specific scenario, you could use window.location.reload() after login, though this is less elegant.
iframe considerations: Since your ABP Angular app runs inside an iframe, you may also want to use postMessage API to communicate the login success to the parent window if needed.
Please try this solution and let us know if you need further assistance.
Best regards
Hi @MartinD
Thank you for your feedback regarding row details functionality in data tables.
ngx-datatable DirectlySince ABP uses ngx-datatable under the hood, you can use its row-detail feature directly by replacing <abp-extensible-table> with <ngx-datatable>:
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
@Component({
imports: [NgxDatatableModule],
template: `
<ngx-datatable #table [rows]="data.items" [count]="data.totalCount" [list]="list">
<ngx-datatable-row-detail [rowHeight]="'100%'">
<ng-template let-row="row" ngx-datatable-row-detail-template>
<div class="p-3">{{ row.name }} - Details here</div>
</ng-template>
</ngx-datatable-row-detail>
<!-- Expand/Collapse Column -->
<ngx-datatable-column [width]="50" [sortable]="false">
<ng-template let-row="row" let-expanded="expanded" ngx-datatable-cell-template>
<a href="javascript:void(0)" (click)="table.rowDetail.toggleExpandRow(row)">
<i class="fa" [class.fa-chevron-down]="!expanded" [class.fa-chevron-up]="expanded"></i>
</a>
</ng-template>
</ngx-datatable-column>
<!-- Your other columns -->
</ngx-datatable>
`
})
export class MyComponent { }
📚 ngx-datatable Documentation: https://swimlane.gitbook.io/ngx-datatable/api/row-detail
We have implemented row-detail support directly in <abp-extensible-table> You can now use the new child component:
<abp-extensible-table [data]="data.items" [list]="list">
<abp-extensible-table-row-detail>
<ng-template let-row="row">
<div class="p-3">{{ row.name }} - Details here</div>
</ng-template>
</abp-extensible-table-row-detail>
</abp-extensible-table>
This approach preserves ABP's extensibility features (entity props, actions, etc.) while adding row-detail functionality.
📌 Track this feature: https://github.com/abpframework/abp/issues/24635
Best regards, ABP Team
Hello @Yaduraj.Shakti Can you give me email address for i send example project
Hi Yaduraj
Let me address your questions one by one:
AuthService.login() and related infrastructure expect JWT tokens and attempt to decode them. Since reference tokens are opaque, they cannot be decoded on the client side./connect/token endpoint directly (e.g., password or authorization code flow).access_token (opaque) and refresh_token securely. Prefer in-memory or sessionStorage for the access token to reduce XSS exposure./connect/userinfo or /api/account/my-profile) instead of decoding the token.AuthService.login() with Reference TokensAuthService.login() at the moment. All built-in identity services assume JWTs./connect/revocation endpoint for both access and refresh tokens. With reference tokens, revocation is immediate, since resource servers perform introspection on every request.client_secret is never exposed in browser code.loginUsingGrant() + custom token storageAuthService.login() and either use loginUsingGrant() or call the token endpoint manually.AuthService.login() does not currently support this scenario. If you prefer built-in features, you would need to switch back to JWTs and use short-lived tokens or backchannel checks to approximate immediate revocation.
If you would like, we can provide you with a sample implementation project demonstrating how to handle login, token storage, refresh, and revocation in Angular using reference tokens.
Angular Team @ Abp Framework
[pablo@ccalp.net] said: Yeah, I saw that alread, got the guard code from the branch and tested it, didn't work.
Hi Pablo,
Thanks for the details you've shared so far.
Could you please share the example where you tested the asyncAuthGuard?
This guard was specifically designed to help prevent the login redirect loop issue, especially after upgrading to v9.2.x.
We’d like to review your usage and see if anything might be missing or misaligned with the intended pattern.
A minimal example (GitHub repo or zip) would be very helpful.
Thanks,
Angular Team @ Volosoft