Получить текущего пользователя в действии ApiController без передачи идентификатора пользователя в качестве параметра

97

Как получить текущего пользователя в безопасном действии ApiController, не передавая userName или userId в качестве параметра?

Мы предполагаем, что это доступно, потому что мы находимся в безопасном действии. Находиться в безопасном действии означает, что пользователь уже прошел аутентификацию и у запроса есть токен-носитель. Учитывая, что WebApi авторизовал пользователя, может быть встроенный способ доступа к userId без необходимости передавать его в качестве параметра действия.

Шон Латтин
источник
Пожалуйста, посмотрите этот ответ: stackoverflow.com/a/26453782/3290276 Добавить претензию помогло
Габриэла Масиас

Ответы:

149

В WebApi 2 вы можете использовать RequestContext.Principalиз метода ApiController

Даррел Миллер
источник
1
Похоже, у нас нет этой собственности. Хм. Возможно, мы используем старую версию WebApi.
Shaun Luttin
2
@ShaunLuttin Хорошо, поэтому, если вы используете Web API 1, то вы, я считаю, что в ApiController есть свойство Prinicpal. Это просто причудливая оболочка для доступа к коллекции Request.Properties. Главный объект хранится в этом словаре.
Даррел Миллер
6
Только не забывайusing Microsoft.AspNet.Identity;
Overlord
1
@DarrelMiller есть ли способ получить то же самое (например, контекст запроса) из других частей кода (не внутри контроллера).
Аджай Арадхья
2
@AjayAradhya Только если вы пройдете туда. Предыдущие исследования веб-фреймворков показали, что использование статических свойств для доступа к контексту запроса вызывает всевозможные архитектурные проблемы. Сначала это удобно, но в долгосрочной перспективе это причиняет оооочень много боли.
Даррел Миллер
36

Вы также можете получить доступ к принципалу, используя Userсвойство on ApiController.

Итак, следующие два утверждения в основном одинаковы:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Патрик
источник
15
Я пытаюсь использовать то, что вы здесь написали, но функция GetUserId () всегда возвращает null. Пользователь авторизован, я передаю токен-носитель, а у ApiController есть заголовок [Authorize]
Джошуа Охана,
Функция GetUserId () возвращает идентификатор, только если у пользователя есть утверждение NameIdentifier. Пример решения этой проблемы см. В ответе Освальдо здесь: stackoverflow.com/questions/19505526
jramm
14

Подсказка заключается в автоматически созданном контроллере учетных записей Webapi2.

Это свойство с геттером определено как

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

и чтобы получить UserManager - в WebApi2 -do as Romans (читается как AccountController)

public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

Это должно быть совместимо в IIS и в режиме собственного хоста.

Каран Бхандари
источник
7

Ни одно из приведенных выше предложений не помогло мне. Следующее сделал!

HttpContext.Current.Request.LogonUserIdentity.Name

Думаю, существует множество сценариев, и этот сработал для меня. В моем сценарии использовались интерфейс AngularJS и серверное приложение Web API 2, оба работали под IIS. Мне пришлось настроить оба приложения на запуск исключительно под Windows Authentication.

Нет необходимости передавать какую-либо информацию о пользователе. Браузер и IIS обмениваются учетными данными вошедшего в систему пользователя, и веб-API имеет доступ к учетным данным пользователя по запросу (я полагаю, из IIS).

Каннанкерил
источник
6

Ответ Карана Бхандари хорош, но добавленный в проект AccountController, скорее всего, является файлом Mvc.Controller. Для того, чтобы преобразовать его ответ для использования в изменении ApiController HttpContext.Current.GetOwinContext()к Request.GetOwinContext()и убедитесь , что вы добавили следующие 2 usingзаявления:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
Джефф Лич
источник
5

В .Net Core используется User.Identity.Nameдля получения заявки на имя пользователя.

Венкатеш Муниянди
источник
2
User.Identity.Nameполучает значение утверждения имени . Это не относится к Active Directory.
Нейт Барбеттини
@Nate Спасибо за ваш комментарий, я исправил
Венкатеш Муниянди
3

Если вы используете Asp.Identity UseManager, он автоматически устанавливает значение

RequestContext.Principal.Identity.GetUserId ()

на основе IdentityUser, который вы используете при создании IdentityDbContext .

Если когда-либо вы реализуете настраиваемую таблицу пользователей и аутентификацию на предъявителя токена owin, пожалуйста, проверьте мой ответ.

Как получить контекст пользователя во время вызовов веб-API?

Надеюсь, это все еще помогает. :)

пампи
источник
1
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null 
        && HttpContext.Current.User.Identity.Name != null)
{
    userName = HttpContext.Current.User.Identity.Name;
    userId = HttpContext.Current.User.Identity.GetUserId();
}

Или на основе комментария Даррела Миллера, возможно, сначала используйте это, чтобы получить HttpContext.

// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    

Смотрите также:

Как получить доступ к HTTPContext из действия веб-API

Шон Латтин
источник
5
Не используйте HttpContext, поскольку он ограничивает возможности вашего хостинга и затрудняет тестирование кода.
Даррел Миллер
Объект HttpContext не будет в словаре, если вы используете Self-host или OwinHttpListener размещены
Даррел Миллер