Передача ClaimsPrincipal из контроллера в службу - PullRequest
0 голосов
/ 10 июня 2019

Я довольно новичок в .NET Core, но я пытаюсь написать свой код как можно более приверженным принципам SOLID.

У меня есть сценарий, когда пользователь, который зарегистрировался на моем сайте, может решить войти в систему с учетной записью Facebook, которая использует тот же адрес электронной почты; который выдает ошибку, потому что поле электронной почты в моей таблице пользователей уникально.

Мое решение для этого было создать ассоциативную таблицу Users_Facebook, например ...

enter image description here

В моем контроллере, где я регистрирую пользователя; чтобы получить идентификатор пользователя, я реализовал сервис для (A. Проверьте таблицу user_facebook для существующего пользователя или (B. Чтобы связать идентификатор пользователя Facebook с существующим пользователем на основе электронной почты.

            [Route("api/Users")]
            [HttpPost]
            public async Task<int> RegisterUser()
            {
                var userId = await userService.GetUserIdAsync(User);
                var email = User.Claims.First(e => e.Type == "emails").Value;
                var user = await _unitOfWork.Users.GetUserByIdAsync(userId);

                // Check contacts to see if one needs to be associated with a user
                var contact = await _unitOfWork.Contacts.GetContactByEmail(email);
                ...

Сервисный фрагмент:

            public async Task<string> GetUserIdAsync(ClaimsPrincipal authedUser)
            {
                var userId = authedUser.Claims.First(e => e.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                var email = authedUser.Claims.First(e => e.Type == "emails").Value;

                var identityProvider = authedUser.HasClaim(e => e.Type == "http://schemas.microsoft.com/identity/claims/identityprovider") ?
                    authedUser.Claims.First(e => e.Type == "http://schemas.microsoft.com/identity/claims/identityprovider").Value : null;
                ...

Мой вопрос: что-то не так с этим? Это нормально, что я передаю ClaimsPrincipal своему сервису? Или я нарушаю какую-то лучшую практику? Если я полностью ухожу, кто-нибудь может предложить лучший способ сделать это?

Заранее спасибо

1 Ответ

1 голос
/ 10 июня 2019

Лично я бы не передавал ClaimsPrincipal в метод.Вместо этого передайте IHttpContextAccessor в конструктор вашего сервиса.Таким образом, его можно зарегистрировать в контейнере DI, выполнив следующее:

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

Затем в своем классе обслуживания введите IHttpContextAccessor следующим образом:

public class MyClass(IHttpContextAccessor context)
{
}

Это означает, что у вас есть доступк текущему контексту из вашего класса без необходимости передавать его через метод.

Чтобы получить доступ к текущему зарегистрированному пользователю, просто получите к нему доступ следующим образом:

var username = Context.User.Identity.Name;

...