How to read user claims from Automapper Value Resolver
Published: 2021-06-10 21:33:44

Sometimes we need to send to our services objects that include existing data in the user’s claims.

To avoid fattening controllers, let’s see how to make Automapper do this work for us.

*In our example, we will try to create a company and only receive the name and description, but obviously, we are interested in knowing which user has made this action.*

*The model that exposes the API is CreateCompany and the DTO that we send to the service is CreateCompanyDto. Both models are the same, except the last one, which incorporates a property that stores the user’s identifier.*

**Step 1: Install Nuget packages**

To make this solution to work correctly, we will need these two packages:
- [Automapper](https://www.nuget.org/packages/AutoMapper)
- [Automapper.Extensions.Microsoft.DependencyInjection](https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/)

**Step 2: Register IHttpContextAccessor interface into DI container**

Why? because *IHttpContextAccessor* is not registered by default for performance reasons. You can read on [Github](https://github.com/aspnet/HttpAbstractions/issues/473) a thread with a discussion about it.

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
    
    services.AddAutoMapper(configuration =>
    {
        configuration.AddProfile<CompanyProfile>();
    });

    services.AddMvc();
}
```

**Step 3: Create Automapper profile**

On our *Automapper* profile, we will specify which *"custom value solver"* we will use to recover the desired value of the user's claims

```csharp
public class CompanyProfile : Profile
{
    public CompanyProfile()
    {
        CreateMap<CreateCompany, CreateCompanyDto>()
            .ForMember(destination => destination.UserId, option => option.ResolveUsing<UserIdResolver>());
    }
}
```

**Step 4: Create "Custom Value Resolver"**

We must inject *IHttpContextAccessor* interface on class constructor so that afterwards, the "Resolve" method is able to read the property.

In this case, we read "NameIdentifier" claim as our user identifier, but we can read anything.

```csharp
public class UserIdResolver : IValueResolver<object, object, string>
{
    private readonly IHttpContextAccessor _contextAccessor;

    public UserIdResolver(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public string Resolve(object source, object destination, string destinationMember, ResolutionContext context)
    {            
        return _contextAccessor.HttpContext.User.Claims
            .Where(x => x.Type == ClaimTypes.NameIdentifier)
            .Select(c => c.Value).SingleOrDefault();
    }
}
```

**Step 5: Create controller and mapping data**

Now, we will be able to map both classes in a single line and this is because Automapper will be in charge of recovering the value that we need from the claims.

```csharp
[HttpPost]
[Authorize]
public async Task<IActionResult> CreateCompanyAsync(CreateCompany request)
{
    var mapped = _automapper.Map<CreateCompanyDto>(request);
    
    return Ok(await _companyService.CreateCompanyAsync(mapped));
}
```

Notice: [This post was published originally on Medium platform on april 17, 2018](https://medium.com/@sergiobarriel/how-to-read-user-claims-from-automapper-value-resolver-1051d54235f2)