Open Closed

OpenIddcit server event handler not be fired #9748


User avatar
0
trendline created

I want to implement some actions (such as given award points to a user daily if the user sign in every day), I need to add an event to OpenIddict server event that it could fire an event handler to implement the logistics, I have followed the article add the event handler and registered in AuthServer project (a micro-services architecture solution), but the event handler not fired and no logs logged, is there any suggestions to debug, or I am using an incorrect way to configure the event handler?

  • Exception message and full stack trace: No
  • Steps to reproduce the issue: Create an OpenIddictServerEvents.ProcessSignInContext event handler and registered, some code as below:
public class DailyPointsHandler : IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>//, ITransientDependency
{
    public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
    .UseScopedHandler<DailyPointsHandler>()
    .SetOrder(100_000)
    .SetType(OpenIddictServerHandlerType.Custom)
    .Build();

    private readonly IdentityUserManager _userManager;
    private readonly IClock _clock;
    private readonly ILogger<DailyPointsHandler> _logger;
    private readonly IRewardPointsHistoriesAppService _rewardPointsHistoriesAppService;
    private readonly IUnitOfWorkManager _unitOfWorkManager;

    public DailyPointsHandler(
        IdentityUserManager userManager,
        IClock clock,
        ILogger<DailyPointsHandler> logger,
        IRewardPointsHistoriesAppService rewardPointsHistoriesAppService,
        IUnitOfWorkManager unitOfWorkManager)
    {
        _userManager = userManager;
        _clock = clock;
        _logger = logger;
        _rewardPointsHistoriesAppService = rewardPointsHistoriesAppService;
        _unitOfWorkManager = unitOfWorkManager;

        _logger.LogInformation("DailyPointsHandler constructor initialized");
    }

    public async ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
    {
        _logger.LogInformation("进入每日积分处理器");

        if (context is null) throw new ArgumentNullException(nameof(context));

        // 跳过客户端凭证流程和刷新令牌流程
        if (context.Request.IsClientCredentialsGrantType() ||
            context.Request.IsRefreshTokenGrantType())
        {
            _logger.LogInformation("跳过非用户登录流程");
            return;
        }

        // 获取用户ID
        var userId = context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value;
        if (string.IsNullOrEmpty(userId))
        {
            _logger.LogWarning("无法从声明中获取用户ID");
            return;
        }

        try
        {
            using var uow = _unitOfWorkManager.Begin(requiresNew: true);

            var user = await _userManager.FindByIdAsync(userId);
            if (user == null)
            {
                _logger.LogWarning("用户未找到: {UserId}", userId);
                return;
            }

            if (user != null)
            {
                var rewardPointsHistoryCreate = new RewardPointsHistoryCreateDto();
                rewardPointsHistoryCreate.UserId = user.Id;
                rewardPointsHistoryCreate.RewardPointType = RewardPointType.DailySignIn;
                await _rewardPointsHistoriesAppService.CreateAsync(rewardPointsHistoryCreate);
                await uow.CompleteAsync();
                _logger.LogInformation("用户 {UserName} 获得每日登录奖励", user.UserName);
            }

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "每日积分赠送处理失败");
            // 失败时继续登录流程,不影响认证
        }

    }

}

registered it at:

  private void PreConfigureOpenIddict(IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
    {
        PreConfigure<OpenIddictBuilder>(builder =>
        {
            builder.AddValidation(options =>
            {
                options.AddAudiences("AuthServer");
                options.UseLocalServer();
                options.UseAspNetCore();
            });
            builder.AddServer(options =>
            {
                options.AddEventHandler<ProcessSignInContext>(builder =>
                    builder.UseInlineHandler(context =>
                    {
                        // Attach custom metadata to the configuration document.
                        //context.Metadata["custom_metadata"] = 42;
                        context.Logger.LogInformation("Processing sign-in event in inline handler for user {userId}.", context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value);

                        return default;
                    }));
            });
        });

        PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
        {
            serverBuilder.AddEventHandler(DailyPointsHandler.Descriptor);
            serverBuilder.AddEventHandler(SignOutEventHandler.Descriptor);
            serverBuilder.AddEventHandler<ProcessSignInContext>(builder =>
                builder.UseInlineHandler(context =>
                {
                    // Attach custom metadata to the configuration document.
                    //context.Metadata["custom_metadata"] = 42;
                    context.Logger.LogInformation("Processing sign-in event in inline handler for user {userId}.", context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value);

                    return default;
                }));
        });
        }
Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

5 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • To ensure your custom OpenIddict server event handler (e.g., for ProcessSignInContext) is fired in an ABP microservices solution, follow these steps and debugging suggestions:
    1. Correct Registration Location
      • Register your handler using PreConfigure<OpenIddictServerBuilder> in your AuthServer module's PreConfigureServices method.
      • Example:
    public override void PreConfigureServices(ServiceConfigurationContext context)
         {
             PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
             {
                 serverBuilder.AddEventHandler(DailyPointsHandler.Descriptor);
             });
         }
    
    • Avoid registering the same handler in both OpenIddictBuilder and OpenIddictServerBuilder. Use only OpenIddictServerBuilder for server events.
    1. Handler Lifetime

      • If your handler depends on scoped services (like IUnitOfWorkManager), use .UseScopedHandler<DailyPointsHandler>() in the descriptor.
      • Ensure your handler is not registered as a singleton if it depends on scoped services.
    2. Check Event Handler Order

      • The SetOrder(100_000) is usually fine, but if other handlers short-circuit the pipeline before yours, your handler may not be called. Try lowering the order value to ensure it runs earlier.
    3. Logging and Diagnostics

      • Enable verbose logging for OpenIddict to see if your handler is being invoked or if there are pipeline issues:
    var loggerConfiguration = new LoggerConfiguration()
             .MinimumLevel.Debug()
             .MinimumLevel.Override("OpenIddict", LogEventLevel.Verbose)
             .WriteTo.File("Logs/openiddict.txt");
    
    • Also, ensure your logger is properly configured and that log files are being written.
    1. Validate Handler Execution
      • Add a simple inline handler for ProcessSignInContext to verify if any handler is being called:
    serverBuilder.AddEventHandler<ProcessSignInContext>(builder =>
             builder.UseInlineHandler(context =>
             {
                 context.Logger.LogInformation("Inline sign-in handler fired for user {userId}.", context.Principal?.FindFirst(OpenIddictConstants.Claims.Subject)?.Value);
                 return default;
             }));
    
    • If this inline handler is not triggered, the event itself may not be firing due to pipeline misconfiguration.
    1. Check Grant Types

      • Your handler skips client credentials and refresh token grants. Make sure your sign-in flow is not using these grant types.
    2. Microservices Considerations

      • Ensure the AuthServer is the only service handling authentication and that requests are routed correctly.
      • If using multiple environments or containers, confirm the correct module is being loaded and configured.
    3. No Duplicate Registrations

      • Avoid registering the same handler multiple times or in both OpenIddictBuilder and OpenIddictServerBuilder.
    4. Restart and Clean Build

      • After changes, do a clean build and restart your AuthServer to ensure all configurations are applied.

    If after these steps your handler is still not firing, try creating a minimal reproduction project with only the handler and registration logic to isolate the issue.

    Sources:


    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    trendline created

    The simple inline handle is not triggered, the event itself may not be firing due to pipeline misconfiguration, could you give some suggestions which pipeline misconfiguration?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please add your code to a new app template project and share it.

    liming.ma@volosoft.com

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    trendline created

    Thanks for the help from Maliming, the auth server UI login is a cookie authentication, not the token scenario, added below code auth server module works fine

    ` context.Services.ConfigureApplicationCookie(options => { var previousOnSignedIn = options.Events.OnSignedIn; options.Events.OnSignedIn = async cookieSignedInContext => { await previousOnSignedIn(cookieSignedInContext);
    };

    var previousOnSigningOut = options.Events.OnSigningOut;
    options.Events.OnSigningOut = async cookieSigningOutContext =>
    {
        await previousOnSigningOut(cookieSigningOutContext);    
    };
    

    }); `

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You’re welcome. 👍

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
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.8.0-preview. Updated on September 28, 2026, 11:44
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.