如何在OpenIdConnect TokenValidated偶数处理程序中访问会话

时间:2018-06-29 06:18:04

标签: asp.net-core

我有一个ASP.NET Core 2.1 MVC应用程序,其中已配置OpenIdConnect提供程序进行身份验证。启动类如下所示:

public void ConfigureServices(IServiceCollection services)
    {

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => false;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        services.AddDistributedMemoryCache();
        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(1200);
            options.Cookie.HttpOnly = true;
        });

        services.AddHttpContextAccessor();
        services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddTransient<IClientDataHandler, ClientDataHandler>();

        services.AddAuthentication(options => .AddOpenIdConnect("oidc", options =>
            {
                ...


                options.Events.OnTokenValidated = async x =>
                {
                    var serviceScopeFactory = services.BuildServiceProvider().GetRequiredService<IServiceScopeFactory>();
                    ...

                    await x.HttpContext.Session.LoadAsync(new CancellationToken()); --does NOT work
                    x.HttpContext.Session.Set("clients", Utils.ObjectToByteArray(someData)); --does NOT work

                };}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseAuthentication();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSession();
        app.UseCookiePolicy();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

尽管这使我可以在任何控制器或服务中使用HttpContext.Session(通过注入IHttpContextAccessor),但不能在TokenValidated事件处理程序中使用Session。有帮助吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

您不应在事件处理程序中构建服务提供者。启动期间不执行此操作。服务提供商建立之后很久,身份验证处理程序就会在每个请求上执行该操作。

options.Events.OnTokenValidated = async context =>
{
    // don't do this...service provider is already built
    var serviceScopeFactory = services.BuildServiceProvider().GetRequiredService<IServiceScopeFactory>();
};

相反,您可以从HttpContext.RequestServices访问内置的服务提供商。

options.Events.OnTokenValidated = async context =>
{
    var serviceScopeFactory = context.HttpContext.RequestServices.GetRequiredService<IServiceScopeFactory>();
};