Base solution for your next web application

Activities of "JapNolt"

Hi @japnolt

Sorry for the late reply. Are you using Redis on your app ?

Yes we are using redis on our app as well as using the per request redis.

Our project is hosted in azure and is replicated across 3 nodes. There seems to be an issue with the Dashboard where we receive a "page not found" exception on a brand new dashboard(or after resetting to default) when clicking add new widget. The default dashboard definition creates a page with a unique id (guid), which seems to be cached locally but not in our redis cache, and so wont be the same id when the next api call is fetched and it hits a different node.

This video shows the issue: https://landiscomputer-my.sharepoint.com/:v:/g/personal/gavin_landistechnologies_com/EViEe61wZJlCvFYme4gIsdUBEknxr4_v-JVvViMdSOD4KQ?e=xg52jc

Also this shows every third request, works as expected, when the api hits the first node that generated the dashboard definition: https://landiscomputer-my.sharepoint.com/:v:/g/personal/gavin_landistechnologies_com/EVek59wkW5FHg5bQryj1vGIByoxZBx8qe5DQ5-ul63Zhpw?e=LwXmkL

What is the recommend solution to this?

Question

There is a security vulnerability on the register and login page as reported in this issue:

https://github.com/aspnetzero/aspnet-zero-core/issues/4649

Is there a workaround for this?

If I don't care about using that feature either is it ok to override the UserAccountSynchronizer? Or is there something else I an do to not save that data?

I saw here: https://support.aspnetzero.com/QA/Questions/7845/UserAccount-table-purpose-Multitenancy that it looks like the UserAccounts table is used just for the linked accounts feature. I was wondering if we don't want that feature can we override the Abp.Authorization.Users.UserAccountSynchronizer and simply not save that data there? We are wanting to use a different database for a tenant and they don't want that data outside their database.

Another solution that is possible is to use SignalR Groups although admittedly it does require changes in both the hub and also when sending the message. I have some thoughts about this on this other thread: https://support.aspnetzero.com/QA/Questions/11117/Microsoft-signalR-is-not-working-with-multiple-instances#answer-4522399e-6457-858f-7bdc-3a0504ccce6e

EDIT: I posted to soon. The code below works for sending messages to clients but does not help with tracking a count of clients or if a user is online.

I recently encountered the same problem and decided to use the Groups feature in SignalR. This blog article recommended that and per my limited testing, it works well https://consultwithgriff.com/signalr-connection-ids/

In the OnConnectedAsync, I add the connection to a group for the tenant and also to a group for the user. I would recommend that ANZ adopt this approach because I believe it would work with either a single server or a scaled out system.

I am willing to share more code if you wish.

Here's an example of how I extended the AbpCommonHub

` public class AbpCommonHubExtended : AbpCommonHub { private readonly IOnlineClientManager _onlineClientManager;

    public AbpCommonHubExtended(
        IOnlineClientManager onlineClientManager,
        IOnlineClientInfoProvider clientInfoProvider) : base(onlineClientManager, clientInfoProvider)
    {
        _onlineClientManager = onlineClientManager;
    }

    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();

        var client = _onlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId);

        await Groups.AddToGroupAsync(
            client.ConnectionId,
            GetGroupName_AllClientsForTenant(
                client.TenantId.GetValueOrDefault()));

        await Groups.AddToGroupAsync(
            client.ConnectionId,
            GetGroupName_AllClientsForUser(
                client.TenantId.GetValueOrDefault(),
                client.UserId.GetValueOrDefault()));
    }

    public static string GetGroupName_AllClientsForTenant(int tenantId)
    {
        return $"t_{tenantId}";
    }
    public static string GetGroupName_AllClientsForUser(int tenantId, long userId)
    {
        return $"t_{tenantId}_u_{userId}";
    }
}

`

Thanks @ismcagdas,

I came up with a similar solution. I added a non-existant "page" to the path.

    this._accountService.impersonateTenant(input).subscribe((result: ImpersonateOutput) => {
        let targetUrl =
            this._appUrlService.getAppRootUrlOfTenant(result.tenancyName) +
            'it?impersonationToken=' +
            result.impersonationToken;
        if (input.tenantId) {
            targetUrl = targetUrl + '&tenantId=' + input.tenantId;
        }

        this._authService.logout(true, targetUrl);
    });

note the "it" before ?impersonationToken

@ismcagdas Any update?

  • What is your product version? 10.5
  • What is your product type (Angular or MVC)? Angular
  • What is product framework type (.net framework or .net core)? .net core
  • single solution

When impersonating a tenant, the site just redirects to the login page without any error. It works fine when debugging locally but not when deployed to Azure as a single solution.

It appears that when the FE redirects to https://sitename/?impersonationToken=<sometoken>&tenantId=<tenantid> that the backend just redirects the request to index.html and does not pass along the query parameters.

I've replicated this problem in a clean project download. You can test here: https://testanz105.azurewebsites.net/account/login

Showing 11 to 20 of 57 entries