Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve users http data in repository service

I am currently building an application where each user has an unique key stored in the users' session storage. This key is used to decrypt the users data in the database. Since the repository layer of the application handles database queries (using Dapper) I would like the decryption to take place there.

Now the problem: I can retrieve the users key from the session storage, pass it to the controller, then to the service then to the repository using a parameter of name "key" in each method that is chained. Is there a way to pass a key from the controller through to the repository layer without having to include the key manually in every call?

If there is a better solution than to store it in session storage I am open to it, if it is going to make this easier.

The encryption system I am following is as follows (from another SO answer): Encryption mechanism

like image 353
Tachyon Avatar asked Jun 10 '20 20:06

Tachyon


2 Answers

You can inject IHttpContextAccessor in your repository or other related business services to retrieve user key.

Suppose you send user key in Header of Http requests as UserKey:

In your Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddHttpContextAccessor();
    ...
}

In your Repository:

public Repository(IHttpContextAccessor httpContextAccessor, ...)
{
    ...
    var userKey = httpContextAccessor.HttpContext.Request.Headers["UserKey"].FirstOrDefault();

    // Or if you send it as cookie: 
    // var userKey = httpContextAccessor.HttpContext.Request.Cookies["UserKey"];
    ...
}
like image 92
Arman Ebrahimpour Avatar answered Oct 09 '22 00:10

Arman Ebrahimpour


Of course you could do it like in accepted answer, but still i would not recommend it

I assume you have some assembly like ProjectName.Repositories or ProjectName.DAL where all of your repositories are To use IHttpContextAccessor there you should install Microsoft.AspNetCore.Http as a dependency

So now your repository level knows about "what framework we are using to work with requests" and it uses current HttpContext to get some data

But to provide low coupling between components we should not depend on details like this

So we could write some user-defined container class to transfer UserKey to our repository level

there is code for my suggestion :

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<UserKeyContainer>();
    services.AddTransient<IUserRepository, UserRepository>();
    ...
}

somewhere in the Abstraction or Dto layer you'll have

public class UserKeyContainer
{
    public string UserKey { get; set; }
}

controller code :

[Route("[controller]")]
public class UserController : Controller
{
    private readonly UserKeyContainer _keyContainer;
    private readonly IUserRepository _repository;
    public UserController(UserKeyContainer keyContainer, IUserRepository repository)
    {
        _keyContainer = keyContainer;
        _repository = repository;
    }

    [HttpGet("")]
    public IActionResult Get()
    {
        _keyContainer.UserKey = "dasdasd"; //you should get UserKey from request there
        _repository.SomeMethod();
        return Ok();
    }
}

and repository :

public class UserRepository : IUserRepository
{
    private readonly UserKeyContainer _keyContainer;
    public UserRepository(UserKeyContainer keyContainer)
    {
        _keyContainer = keyContainer;
    }

    public void SomeMethod()
    {
        var key = _keyContainer.UserKey;
    }
}

Also you could use action filters to intercept requests and set HttpContext data to UserKey

like image 3
Roman Kalinchuk Avatar answered Oct 09 '22 01:10

Roman Kalinchuk