Activities of "Frontis2"

hello,

autosave was the issue.

Am closing it now.

Answer

Alex, this might help?:

https://github.com/face-it/Hangfire.Tags

Thanks for the answer.

Nope, this does not help. Actually: how only the create (before the background job fires), the update is not visible in the audit log.

using (currentPrincipalAccessor.Change(newPrincipal))
{
    using (var uow = unitOfWorkManager.Begin(requiresNew: true))
    {
        using (var auditingScope = auditingManager.BeginScope())
        {
            configuration = await configurationRepository.GetAsync(Convert.ToInt64(args.ProjectInfo?.ConfigurationId));
            var advicefileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(pdfAdviceResponseTask.Result), adviceFileName));
            var billOfMaterialsFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(pdfBillOfMaterialsResponseTask.Result), BillOfMaterialsFileName));
            var anchoringZonesFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(Encoding.UTF8.GetBytes(anchoringZonesSVGTask.Result)), L["DownloadAnchoringDrawing:Filename", args.Configurator.RoofLayoutInformation.TypeOfRoof.Value.ToString()]));
            var zonesFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(Encoding.UTF8.GetBytes(zonesSVGTask.Result)), L["DownloadZoneDrawing:Filename", args.Configurator.RoofLayoutInformation.TypeOfRoof.Value.ToString()]));
            Task.WaitAll(advicefileTask, billOfMaterialsFileTask, anchoringZonesFileTask, zonesFileTask);

            args.Context?.WriteLine($"Started configuring files to database...'");
            configuration.AdvicePDFId = advicefileTask.Result.Id;
            configuration.BillOfMaterialsPDFId = billOfMaterialsFileTask.Result.Id; // TODO: aanpassen naar billofmaterials
            configuration.AnchoringDrawingId = anchoringZonesFileTask.Result.Id;
            configuration.ZoneDrawingId = zonesFileTask.Result.Id;

            await configurationRepository.UpdateAsync(configuration);

            await auditingScope.SaveAsync();
            await uow.CompleteAsync();
        }
    }
}

Thanks for the response,

Now a log rule is fired, but with no properties. Even if i reload the configuration, within the scope, first.

using (currentPrincipalAccessor.Change(newPrincipal))
{
    using (var auditingScope = auditingManager.BeginScope())
    {
        configuration = await configurationRepository.GetAsync(Convert.ToInt64(args.ProjectInfo?.ConfigurationId));
        var advicefileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(pdfAdviceResponseTask.Result), adviceFileName));
        var billOfMaterialsFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(pdfBillOfMaterialsResponseTask.Result), BillOfMaterialsFileName));
        var anchoringZonesFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(Encoding.UTF8.GetBytes(anchoringZonesSVGTask.Result)), L["DownloadAnchoringDrawing:Filename", args.Configurator.RoofLayoutInformation.TypeOfRoof.Value.ToString()]));
        var zonesFileTask = UploadFileAsync(new RemoteStreamContent(new MemoryStream(Encoding.UTF8.GetBytes(zonesSVGTask.Result)), L["DownloadZoneDrawing:Filename", args.Configurator.RoofLayoutInformation.TypeOfRoof.Value.ToString()]));
        Task.WaitAll(advicefileTask, billOfMaterialsFileTask, anchoringZonesFileTask, zonesFileTask);

        args.Context?.WriteLine($"Started configuring files to database...'");
        configuration.AdvicePDFId = advicefileTask.Result.Id;
        configuration.BillOfMaterialsPDFId = billOfMaterialsFileTask.Result.Id;
        configuration.AnchoringDrawingId = anchoringZonesFileTask.Result.Id;
        configuration.ZoneDrawingId = zonesFileTask.Result.Id;

        await configurationRepository.UpdateAsync(configuration);

        await auditingScope.SaveAsync();
    }
}

This is not the answer.

  • Steps to reproduce the issue:
  • Follow https://abp.io/community/articles/how-to-change-the-currentuser-in-abp-i3uu1m7g#gsc.tab=0 using Hangfire background task
  • Example code that is not working in our situation...
example deleted
  • The example above is fired after someone changes a configuration. Generating files takes a while, So we needed a background job. We want the change to be logged in the audit log. But nothing gets logged, within the background job. The configuration change made by the user (outside the background job), is visible in the audit log.
  • We use HangFire as background task scheduler.

private void ConfigureAuditing() { Configure<AbpAuditingOptions>(options => { options.IsEnabledForAnonymousUsers = false;

    options.EntityHistorySelectors.Add(
        new NamedTypeSelector(
            "MySelectorName",
            type =>
            {
                return type == typeof(Project) || type == typeof(Configuration);
            }
        )
    );
});

}

  • ABP Framework version: v7.1.1
  • UI type: MVC
  • DB provider: EF Core

Currently am trying to add an external login, using Azure Active Directory. The purpose of this external login, is to be used by administrators only.

As described in the community blog post, I did the following... Note the CustomOpenIdConnectEvents class...

private void ConfigureExternalProviders(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication()
          //Omitted other third party configurations
          .AddOpenIdConnect("AzureOpenId", "Sign in with Microsoft", options =>
          {
              options.Authority = $"https://login.microsoftonline.com/{configuration["AzureAd:TenantId"]}/v2.0/";
              options.ClientId = configuration["AzureAd:ClientId"];
              options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
              options.CallbackPath = configuration["AzureAd:CallbackPath"];
              options.ClientSecret = configuration["AzureAd:ClientSecret"];
              options.RequireHttpsMetadata = false;
              options.SaveTokens = true;
              options.GetClaimsFromUserInfoEndpoint = true;
              options.Scope.Add("email");
              options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
              options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
              options.SignInScheme = IdentityConstants.ExternalScheme;

              options.EventsType = typeof(CustomOpenIdConnectEvents);
          });
    }

And here is the CustomOpenIdConnectEvents class:

    {
        [UnitOfWork]
        public override async Task TokenValidated(TokenValidatedContext context)
        {
            await base.TokenValidated(context);

            var userManager = context.HttpContext.RequestServices.GetRequiredService<IdentityUserManager>();
            

            var userEmail = context.Principal.FindFirstValue(ClaimTypes.Email);

            var currentUser = await userManager.FindByEmailAsync(userEmail);

            if (currentUser != null)
            {
                var adminRoleName = "admin"; // Replace with your admin role name
                var isInRole = await userManager.IsInRoleAsync(currentUser, adminRoleName);

                if (!isInRole)
                {
                    await userManager.AddToRoleAsync(currentUser, adminRoleName);
                    var identity = context.Principal.Identity as ClaimsIdentity;
                    identity?.AddClaim(new Claim(identity.RoleClaimType, adminRoleName));
                }
            }
        }
    }

The code itself is working. However with the following issues:

  • The user must log out and log back in, before he is admin
    • I think this is because the user account only exists after he hits "register".
  • Am not quite sure if finding the user based on the mail-address is save. However, finding by claim does not work. var currentUser = await userManager.GetUserAsync(context.Principal);

Concrete: How can I make sure users are automatically administrator? Preferably the registration form should be skipped.

  • ABP Framework version: v6.0.1
  • UI type: MVC
  • DB provider: EF Core
  • Identity provider: OpenIddict
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

We're running a project, where a client is calling our ABP api. All happy flows are working as aspected.

Client details:

  • Nuxt framework (Vue) with Axios
  • Request and response example at the end of the message...

For any given reason tokens might expire. In this case, our client should get a HTTP status 401. This is not the case, it is getting a http status 302 found, whish is redirecting to a error page (= 401).

As you can see in the request, the client is sending a X-Requested-With attribute. This is a recommended solution, but not working. Reference 1 (axios Github) Reference 2 (ABP support)

For cookie authentication, there is a workaround. Reference 1 (ABP Github)

private void ConfigureRedirectStrategy(ServiceConfigurationContext context)
{
    // Without this, api calls without "X-Requested-With: XMLHttpRequest"
    // are redirected to identity server login page.
    // We want to return 401:Unauthorized instead of redirecting
    context.Services.ConfigureApplicationCookie(options =&gt;
    options.Events.OnRedirectToAccessDenied = context =&gt;
    {
    context.Response.Headers["Location"] = context.RedirectUri;
    context.Response.StatusCode = 401;
    return System.Threading.Tasks.Task.CompletedTask;
    });
}

As said, this will not work since the client is using Axios for requests.

Concrete question(s): Do you have any ideas how to solve thie issue (status 302 has to be a status 401)? MVC should work properly, so i guess we still have to use the "X-Requested-With: XMLHttpRequest attribute". But why is it not working?

Thanks in advance,

Request

Host: {url}
Connection: keep-alive
sec-ch-ua: "Brave";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
Authorization: Bearer ...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
sec-ch-ua-platform: "Windows"
Sec-GPC: 1
Origin: {url}
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: {url}
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl;q=0.8

Response

Content-Length: 0
Date: Tue, 04 Apr 2023 09:50:10 GMT
Server: Kestrel
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: {url}
Access-Control-Expose-Headers: _AbpErrorFormat
Cache-Control: no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: /Error?httpStatusCode=401
Pragma: no-cache
Set-Cookie: ARRAffinity=...
Set-Cookie: ARRAffinitySameSite=...
Vary: Origin
WWW-Authenticate: Bearer error="invalid_token", error_description="The signing key associated to the specified token was not found.", error_uri="https://documentation.openiddict.com/errors/ID2090"
Request-Context: appId=...
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN```

@gterdem

Thanks for your response.

As a digital agency, we run multiple ABP projects, for multiple customers. And those customers (abp-projects), have multiple clients connecting to them. So multiple clients, that connect to our ABP api's.

We did not make all clients, and therefore it is hard to test them. Is there anything that we should report to the developers of the clients? Other than "please test everything".

Are there significant changes that occur, after the migration, that our customers need to report to their clients? Think about endpoint changes. Is there any difference in how tokens are handled?

As far as we know, all clients follow the openid / oauth2 specs. We did not implement custom code on the ABP side.

If this question is hard to answer, I also do like to know. Anything you know of, is desirable to hear.

Is my question to complicated? I know it is a bit abstract. However, knowing any pitfalls would help us a lot. If there is no known pitfall, I do like to know either.

Showing 1 to 10 of 13 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 18, 2025, 07:10