Starts in:
2 DAYS
5 HRS
36 MIN
11 SEC
Starts in:
2 D
5 H
36 M
11 S

Activities of "alexander.nikonov"

I removed, it tells now

System.ArgumentException: ''Server' is an invalid connection string attribute

So I don't understand what format it wants then.

I don't think this idea would work. We have a customized solution and we use a different DBMS, not MS SQL Server. So I might even not be able to reproduce it on a test ABP project.

Anyway, I am ready to give it a go.

So I am trying to set up a test project - I generated it from "abp suite 8.1.3". But the Migrator throws the exception about the connection string format (I am going to use my free MS SQL Server Express for test purposes).

This is what has been generated by Abp Suite: "Data Source=Test;Integrated Security=yes;" - here the exception tells about unsupported "Integrated Security" parameter.

I've change the format to "Server=MyServerAddress;Database=Test;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=true" - but this format is not undestood also.

  • ABP Framework version: v8.1.3
  • UI Type: Angular
  • Database System: EF Core (Oracle)
  • Auth Server Separated OpenID Server

I still can't get logout to work consistently in my Angular applications.

First of all, I commented the line - just for your information:

    {
        path: '',
        pathMatch: 'full',
        loadChildren: () => import('@my-home-page-package').then(m => m.MyHomeModule),
        // canActivate: [AuthGuard] // This was a logout blocker
    }

Now: A) If i use this code:

    @Injectable()
    export class MyServerErrorInterceptor implements HttpInterceptor {
      constructor(private router: Router) { }
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
          catchError((error: HttpErrorResponse) => {
            if (error.status === 401) {
              this.router.navigate(['/']);
              return EMPTY;
            } else {
              return throwError(error);
            }
          })
        );
      }
    }

and click "Logout" link in the user menu, the logout seems to be working as expected from tab 1 in the browser. However if I have another page being open from the same site in tab 2 - it is not redirected to Login page: instead, I come up with an empty (no navigation menu) home page shown in this tab;

B) If i replace ['/'] with ['/login'] in the code above - both tabs react on this, however I end up with the endless loop, when both tabs try to do something and it never ends; Also - if i have only one tab of the application opened in the browser, I still have a weird situation, when after getting connect/revocat request (twice, btw - ??) and several 401 API requests, I see (so i see traditional openid-configuration and so forth), so I am not actually logged out - but redirected to a home page;

C) If i emulate the situation with a token expiration - removing "local storage" data in the browser, I expect to be redirected to Login page on the next request attempt (instead of giving me error 401). So the setting (B) provides this, however setting (A) redirects me to a no-menu home page;

And in general, logout process visually does not look good: I expect if a user clicks "Logout" - he is redirected to Login page straight away. Instead, I see the navigation menu is being disappeared and still observing a home page while some server operations are taking place;

I have some Middleware in my OpenID Server module to do cleaning work on httpContext.Request.Path.Value == "/connect/logout" scenario (B) (but works fine with scenario (A) - the exception does not happen). So I commented it, but it RANDOMLY affected the described scenario (sometimes it did, sometimes it did not):

    public async Task InvokeAsync(HttpContext httpContext, IAbxRequestContext requestContext, IdentityUserManager userManager)
    {
        await _next(httpContext);
    
        if (httpContext.Request.Path.Value == "/connect/logout")
        {
            await OnSessionEndRequestAsync(httpContext, userManager);
        }
    }
    
    private async Task OnSessionEndRequestAsync(HttpContext httpContext, IdentityUserManager userManager)
    {
        try
        {
            var user = await userManager.GetUserAsync(httpContext.User); //IF IT GETS INVOKED AND CRASHES - IT SEEMS TO AFFECT THE LOGOUT
            //Some cleaning routine - accessing DB, removing entries
        }
        catch(Exception ex)
        {
            _logger.LogError(ex, "Session End handling error");
        }
    }

Thus, I have no clue what might be a real root cause of the logout issue.

I kindly ask you to provide me with the correct settings (code) for a front-end and a back-end settings which might be relevant to the situation.

I cannot provide you with our code, sorry.

My suggestion is to start with a root cause of the exception in the call above. It is:

at System.Threading.CancellationToken.ThrowOperationCanceledException() at System.Threading.CancellationToken.ThrowIfCancellationRequested() at Volo.Abp.Identity.IdentityUserStore.FindByIdAsync(String userId, CancellationToken cancellationToken) at Castle.Proxies.IdentityUserManagerProxy.FindByIdAsync_callback(String userId) at Castle.Proxies.Invocations.UserManager1_FindByIdAsync.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.DynamicProxy.AbstractInvocation.ProceedInfo.Invoke() at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)

whereas httpContext.User is OK (data is ok and it is authenticated).

Understood... Thank you.

Unfortunately there is no better way

Well, maybe Ocelot Gateway project would help it? Will it work to merge localizations from all running sites (i.e. merge the "application-localization" endpoints results) and finally get the full list at the site with Role Management page, will the page "see" all those?

I do have localization for permissions, but the translations are stored in the resource files (in Domain.Shared project) of the respective applications: A, B, C. So to show the display names of all of them on a central Permission Management page, I need to retrieve the translations from those projects.

And to my knowledge, there are only two options here:

  1. to consume all the resources (i.e. Domain.Shared projects - which are now published as Nuget package) in the solution where the Permission Management page is;
  2. make an API call to A, B, C solutions endpoints to retrieve resources on the Permission Management page and map them on resource keys on front-end side;

I don't like variant #1 because of the reasons described previously. And I don't like variant #2 much either, because there could be a lot of excessive data - /api/abp/application-localization endpoint only accepts the language parameter, no any resource key mask...

I thought that maybe there's a better way?

I cannot hardcode display name of the permission in the property, if this is what you meant, because I have a multi-language app, so the permission display name needs to be changed depending on the current UI language.

  • ABP Framework version: v8.1.3
  • UI Type: Angular
  • Database System: EF Core (Oracle)
  • Auth Server Separated

Moving to Redis server and dynamic permissions allowed us to simplify the process of Role / Permission management. So now Redis cache contains permissions of all the running solutions.

However, one problem remained: localization. One of the solutions contains Role / Permission management page which displays ALL the permissions. But each permission localized name resides in the corresponding solution. We don't want to move the permission localization to a separate project.

The most simple way to resolve this would be to consume all the solutions' Domain.Shared projects:

    options.Resources
        .Add<PermissionManagementResource>("en")
        .AddBaseTypes(typeof(SolutionAResource), typeof(SolutionBResource), typeof(SolutionCResource))

But it would create a coupling we want to avoid. We might have a new solution D in future - which means we will have to modify the code above again.

The question is - what is an alternative way to have localization from all the solutions always actual, but still be able to do search by a localized name after receiving the permissions from all the solutions using

    var permissionListResultDto = await _permissionAppService.GetAsync(RolePermissionValueProvider.ProviderName, role.Name);
    

?

What is the project of this error log? You can try to add your code to Domain module.

https://abp.io/support/questions/7699/Random-exception-after-switching-from-IdentityServer-to-OpenDict#answer-3a147d57-7267-7eaf-1d74-ba36bdfea929

Sorry, I am not sure I am following you. The first exception (DI issue) needs to be reproduced yet, I am waiting for my colleague trying to assist me, because I did not manage to get this exception. So I cannot say anything here yet.

But instead I received another exception related to the transaction level. According to your recommendation, I have overriden all the stores with the code you provided for the older version of ABP - in order to override a transaction level. After adding this code, I can see that the Store property is properly filled with my custom class. All the constructors of all three custom stores did invoke - so the code was applied as expected. Still, I received the same exception again at some point. I cannot see how this may ever happen, if all my front-end applications interact with the same OpenId Server where I made the override and - I expect - there is only one "entry point" to reach out the TokenCleanupBackgroundWorker where the exception happens and this "entry point" is the interaction between front-end applications and OpenId Server?

I see no problem with this code in the solution where I received the exception - the Store contains correct class:

It was related to using .First inside the loop. And we had many permissions. Replaced IEnumerable with the Dictionary and now it's fine.

Showing 31 to 40 of 333 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06