Отримайте поточного користувача в межах дії ApiController, не передаючи ідентифікатор користувача як параметр


97

Як отримати поточного користувача в межах захищеної дії ApiController, не передаючи userName або userId як параметр?

Ми припускаємо, що це доступно, оскільки ми перебуваємо в межах безпечної дії. Перебування в безпечній дії означає, що користувач вже пройшов аутентифікацію, а запит має її маркер-носія. З огляду на те, що WebApi дозволив користувача, може бути вбудований спосіб доступу до userId, без необхідності передавати його як параметр дії.


Будь ласка, перегляньте цю відповідь: stackoverflow.com/a/26453782/3290276 Додайте претензію, яка зробила трюк
Габріела Маціас

Відповіді:


149

У WebApi 2 ви можете використовувати RequestContext.Principalзсередини метод на ApiController


1
Здається, у нас немає цього майна. Хм Можливо, ми використовуємо стару версію WebApi.
Шон Луттін

2
@ShaunLuttin Гаразд, тож якщо ви використовуєте Web API 1, то, на вашу думку, на ApiController є властивість Prinicpal. Це просто вигадлива обгортка навколо доступу до колекції Request.Properties. Основний об'єкт зберігається в цьому словнику.
Даррел Міллер

6
Тільки не забувайтеusing Microsoft.AspNet.Identity;
Оверлорд

1
@DarrelMiller чи є спосіб отримати те саме (скажімо контекст запиту) з інших частин коду (не в контролері).
Ajay Aradhya

2
@AjayAradhya Тільки якщо ви передасте його туди. Попередні зусилля щодо веб-фреймворків показали, що використання статичних властивостей для доступу до контексту запиту викликає всілякі архітектурні проблеми. Спочатку це зручно, але це спричиняє дуже багато болю в довгостроковій перспективі.
Даррел Міллер,

36

Ви також можете отримати доступ до комітента, використовуючи Userвластивість на 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

Нехай ця властивість із getter визначена як

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

а для того, щоб отримати UserManager - у WebApi2 -do, як це роблять римляни (читати як AccountController)

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

Це має бути сумісним у IIS та режимі самостійного хосту


7

Жодна з наведених вище пропозицій не спрацювала для мене. Наступні зробили!

HttpContext.Current.Request.LogonUserIdentity.Name

Я припускаю, що існує найрізноманітніший сценарій, і цей для мене спрацював. Мій сценарій включав інтерфейс AngularJS та серверну програму Web API 2, які працювали під IIS. Мені довелося налаштувати обидва додатки на винятково автентифікацію Windows.

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


6

Відповідь Карана Бхандарі хороша, але доданий в проект AccountController, швидше за все, є Mvc.Controller. Щоб перетворити його відповідь для використання в ApiController, змініть HttpContext.Current.GetOwinContext()на Request.GetOwinContext()та переконайтеся, що ви додали наступні 2 usingтвердження:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;


3

Якщо ви використовуєте Asp.Identity UseManager, він автоматично встановлює значення

RequestContext.Principal.Identity.GetUserId ()

на основі IdentityUser, який ви використовуєте для створення IdentityDbContext .

Якщо ви коли-небудь реалізовуєте спеціальну таблицю користувачів та аутентифікацію протоколу Owen token, будь ласка, перевірте мою відповідь.

Як отримати контекст користувача під час дзвінків Web 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 не буде в словнику, якщо ви самостійний хост або хостинговий OwinHttpListener
Даррел Міллер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.