Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access to user credentials in ASP.NET Core middleware

In ASP.NET core (2.1), running on a windows, I am using HttpSys configured with the following authentication schemes:

builder.UseHttpSys(options =>
        {
            options.Authentication.Schemes = AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM;
            options.Authentication.AllowAnonymous = true;
        })

Then in my Startup.Configure() method I am attempting to access the user credentials of the client calling the uri "/sensitiveOperation" as follows:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseAuthentication();

        app.MapWhen(context => context.Request.Path.Equals("/sensitiveOperation") && context.Request.Method.Equals(HttpMethods.Put), subApp =>
        {                
            subApp.Run(async (context) =>
            {
                if (context.User.Identity.Name == "admin")
                {
                    await context.Response.WriteAsync("Performing sensitive operation.");
                    // .. Do Sensitive operation....
                }                    
            });
        });

The example is slightly vulgarised, but the main point is that context.User.Identity.Name is always empty where I would expect to see the name of the AD account which is making the call. Note that the call is done in powershell as follows:

Invoke-WebRequest -Uri http://localhost:5555/sensitiveOperation -Method Put -UseDefaultCredentials

I could put this code in a controller and use the [Authorize] attribute to get the credentials but I would prefer to do this operation before hitting the Mvc pipeline. Is there any way to get the user at this early stage of the pipeline ?

like image 223
Mr Davies Avatar asked Aug 14 '18 15:08

Mr Davies


People also ask

How do I authenticate in .NET Core?

Authentication is the process of determining a user's identity. Authorization is the process of determining whether a user has access to a resource. In ASP.NET Core, authentication is handled by the authentication service, IAuthenticationService, which is used by authentication middleware.

What is IApplicationBuilder in .NET Core?

UseExceptionHandler(IApplicationBuilder) Adds a middleware to the pipeline that will catch exceptions, log them, and re-execute the request in an alternate pipeline. The request will not be re-executed if the response has already started.


2 Answers

Change AllowAnonymous

options.Authentication.AllowAnonymous = false;

If you have anonymous on, and you're not prompting for authentication then the browser isn't going to authenticate. Even if you do send creates asp.net isn't going to get them unless there's an Authenticate attribute on the controller/method or, if you're going the function route, you call signin.

like image 162
blowdart Avatar answered Oct 05 '22 02:10

blowdart


If you would not want to set AllowAnonymous as false, you could try context.ChallengeAsync to authenticate the request based on Credential.

Here are the code:

        app.MapWhen(context => context.Request.Path.Equals("/sensitiveOperation") && context.Request.Method.Equals(HttpMethods.Put), subApp =>
        {
            subApp.Run(async (context) =>
            {
                var authService = context.RequestServices.GetRequiredService<IAuthorizationService>();

                if (!context.User.Identity.IsAuthenticated)
                {
                    //await context.ChallengeAsync("Windows"); //Option1
                    //await context.ChallengeAsync();  //Option2
                    await context.ChallengeAsync(HttpSysDefaults.AuthenticationScheme); //Option3
                }
                if (context.User.Identity.Name == "admin")
                {
                    await context.Response.WriteAsync("Performing sensitive operation.");
                    // .. Do Sensitive operation....
                }
            });
        });

Note, for this way, subApp.Run will run twice, first request is UnAuthenticated, and it will challenge the credentail, second request is Authenticated and context.User.Identity.Name will have value. This process is back-end, this would not be reflected in powershell.

like image 37
Edward Avatar answered Oct 05 '22 00:10

Edward