Glimpse / Glimpse.Prototype

Glimpse v2 prototype
MIT License
185 stars 44 forks source link

Accessing User / Identity Information within AllowClientAccess in .NET 5 #93

Closed rionmonster closed 8 years ago

rionmonster commented 8 years ago

I've been attempting to integrate Glimpse into a small .NET5 application that I have been running in production for some time now and have appeared to hit a minor speed bump.

I'm trying to enable / disable the Glimpse HUD on a by-user basis. After a lengthy discussion of the issue with Nik on Twitter, we determined that this would be the best area to post this issue.

Basically, I cannot figure out the best approach to handle this. I attempted to use the following snippet in hopes of using a predefined collection of user names and matching those with the user within the current request :

services.AddGlimpse().RunningServerWeb(options =>
{
            // Determine if usage is permitted based on the current user (via the Configuration)
            options.AllowClientAccess = httpContext =>
            {
                // Read from a configuration that defines various user names that would have access
                // to the Glimpse analytics
                var enabledUsers = Startup.Configuration.Get<GlimpseConfiguration>("Glimpse");
                // Check if the current user qualifies and handle accordingly
                return enabledUsers.EnabledUsers.Any(u => u.UserName == httpContext.User.Identity.Name);
            };

            options.AllowAgentAccess = httpContext => true;
}

However, it appears that the expected Identity information from httpContext.User.Identity is always null. I've tried moving it around in several areas within the ConfigureServices method with little success.

What would be the best course of action for handling this type of behavior?

avanderhoorn commented 8 years ago

This is definitely a use case we would expect to work. What happens if you shift your authentication middleware to run before Glimpse? To test this, you should be able to move it above the app.UseGlimpse(). My guess is that you have Glimpse running first and its the auth middleware that populates the httpContext.User part of the context, hence it needs to run first. Let me know how that goes.

rionmonster commented 8 years ago

It appears that adjusting the order resolved it.

Previously I had attempted to strictly place the app.UseGlimpse() and services.AddGlimpse() calls either at the top or the bottom of their respective methods, which didn't appear to work. I ended up with the following :

public void ConfigureServices(IServiceCollection services)
 {
           // Omitted for brevity

            // Add Identity services to the services container.
            services.AddIdentity<ApplicationUser, IdentityRole>(i => {
                        i.Password.RequireDigit = false;
                        i.Password.RequireNonLetterOrDigit = true;
                        i.Password.RequireUppercase = false;
                        i.Password.RequireLowercase = false;
                        i.SecurityStampValidationInterval = TimeSpan.FromDays(7);
                    })
                    .AddEntityFrameworkStores<ApplicationDbContext>()                   
                    .AddDefaultTokenProviders();

            // Add MVC services to the services container.
            services.AddMvc();

            // Omitted for brevity 

            // Add Glimpse in for in-app analytics
            services.AddGlimpse().RunningServerWeb(options =>
            {
                options.AllowClientAccess = httpContext =>
                {
                    // Read from a configuration that defines various user names that would have access
                    // to the Glimpse analytics
                    var enabledUsers = Startup.Configuration.Get<GlimpseConfiguration>("Glimpse");
                    // Check if the current user qualifies and handle accordingly
                    return enabledUsers.EnabledUsers.Any(u => u.UserName == httpContext.User.Identity.Name);
                };

                options.AllowAgentAccess = httpContext => true;
            });
}

and

// Configure is called after ConfigureServices is called.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
            // Indicate Kestrel usage
            app.UseIISPlatformHandler();

            // Omitted for brevity

            // Add cookie-based authentication to the request pipeline.
            app.UseIdentity();

            // Add Glimpse in for in-app analytics
            app.UseGlimpse();

            // Omitted for brevity
}

This appears to resolve the issue as I can now actually access the User.Identity.Name as expected, which should set up Glimpse for that user.

On an unrelated note, is there a way to configure the Glimpse requests to use https as opposed to http as the protocol? I currently am playing around with this on a site running on https thus it rejects the Glimpse files as being unsecured.

avanderhoorn commented 8 years ago

Great to hear! The order of ConfigureServices shouldn't matter, the Configure order is the important one as that actually effects the execution order.

On the https front are you wanting to do this locally or remotely?

rionmonster commented 8 years ago

As of right now - locally. However, remote usage would likely be something that I could be interested in.

avanderhoorn commented 8 years ago

The reason I ask is that currently there is a hack that would make it work, but it forces the HttpMessagePublisher to be used rather than the InProcessPublisher. For dev time, this isn't that big of a deal, but in prod, this isn't optimal unless you have more than one web server front end. If you still want to go ahead, let me know and I can walk you though it, in the mean time, create a separate issue for this so that we can track it.