Access user identity from controller in ASP.NET Core Web API

Viewed 6162

As per this documentation:

ASP.NET Core 2.1 Documentation

I should be able to access the user identity using ControllerBase.User or HttpContext.User.

As per the link above:

“Getting the current user's identity from the app's DI service collection is more testable, too, since test identities can be easily injected.”

As I understand, I should inject the identity information using dependency injection in Startup.cs or perhaps in controller's constructor.

However, after endless hours of investigation, I’m not able to find the procedure.

The following steps describe my scenario. I hope someone can guide me in the right direction.

1) Using Visual Studio 2017, create a ASPNET.core Web API project with the following options:

  • Type: API
  • Enable Docker Support: no
  • Authentication: No Authenitication
  • Configure for HTTPS: yes

2) Add AuthDetailsController.cs to the Controllers folders with the following code:

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace CoreWebApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthDetailsController : Controller
    {


        [HttpGet]
        public JsonResult Get()
        {
            var r = new Dictionary<String, Object>();

            r.Add("User.Identities", User.Identities);
            r.Add("User.Claims", User.Claims);
            r.Add("HttpContext.User.Identities", HttpContext.User.Identities);
            r.Add("HttpContext.User.Claims", HttpContext.User.Claims);

            return Json(r );
        }

    }
}

3) Deploy to Azure as a new application

4) Navigate to https://[site_name].azurewebsites.net/api/AuthDetails

5) There is no information about the user identity because the access is anonymous:

{"User.Identities":[{"authenticationType":null,"isAuthenticated":false,"actor":null,"bootstrapContext":null,"claims":[],"label":null,"name":null,"nameClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","roleClaimType":"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"}],"User.Claims":[],"HttpContext.User.Identities":[{"authenticationType":null,"isAuthenticated":false,"actor":null,"bootstrapContext":null,"claims":[],"label":null,"name":null,"nameClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","roleClaimType":"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"}],"HttpContext.User.Claims":[]}

6) Enable Azure authentication with the following options:

  • Action to take when request is not authenticated: Logon with Azure Active Directory.
  • Azure Active directory configuration: Express Mode

7) Open again https://[site_name].azurewebsites.net/api/AuthDetails

8) You are redirected to the login page

9) After the successful login, there no identity information in ControllerBase.User nor HttpContext.User. The response is the same as before enabling authentication.

3 Answers

You have to tell the authentication that needs to be used in your startup.cs.

It would be something like.

services.AddAuthentication(IISDefaults.AuthenticationScheme);

The link to this details can be found on this.

Also on actions in your controller you need to add [Authorize]. Only when this is added you will be able to retrieve the details. If you add at the controller level, for the actions where you don't need authentication you can add [AllowAnonymous]

[HttpGet]
[Authorize]
        public JsonResult Get()
        {
            var r = new Dictionary<String, Object>();

            r.Add("User.Identities", User.Identities);
            r.Add("User.Claims", User.Claims);
            r.Add("HttpContext.User.Identities", HttpContext.User.Identities);
            r.Add("HttpContext.User.Claims", HttpContext.User.Claims);

            return Json(r );
        }

I made it !!!

This documentation pointed me in the right direction.

These are the steps to reproduce my scenario:

1) Using Visual Studio 2017, create a ASPNET.core Web API project with the following options:

  • Type: API
  • Enable Docker Support: no
  • Authentication: No Authenitication
  • Configure for HTTPS: yes

2) Add AuthDetailsController.cs to the Controllers folder with the following code:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace CoreWebApiTest2.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthDetailsController : ControllerBase
    {
        // GET: api/AuthDetails
        [HttpGet]
        public Dictionary<string,string> Get()
        {
            return new Dictionary<string, string> { {"X-MS-CLIENT-PRINCIPAL-NAME", Request.Headers["X-MS-CLIENT-PRINCIPAL-NAME"] },
                                                    {"X-MS-CLIENT-PRINCIPAL-ID", Request.Headers["X-MS-CLIENT-PRINCIPAL-ID"]  } };

        }
    }
}

3) Deploy to Azure as a new application

4) Enable Azure authentication with the following options:

  • Action to take when request is not authenticated: Logon with Azure Active Directory.
  • Azure Active directory configuration: Express Mode

5) Open https://[site_name].azurewebsites.net/api/AuthDetails

6) You are redirected to the login page

7) After the successful login, you get the response:

{"X-MS-CLIENT-PRINCIPAL-NAME":"your_user@your_domain","X-MS-CLIENT-PRINCIPAL-ID":"your_user_ad_guid"}
Related