Я хочу получить текущего пользователя для получения информации о пользователе, например электронной почты. Но я не могу этого сделать в ядре asp.net. Я так запуталась. Это мой код.
HttpContext
почти равно нулю в конструкторе контроллера. Нехорошо привлекать пользователя к каждому действию. Я хочу получить информацию о пользователе один раз и установить его ViewData
;
public DashboardController()
{
var user = HttpContext.User.GetUserId();
}
c#
asp.net-core
asp.net-identity
Мехран Хафизи
источник
источник
Ответы:
РЕДАКТИРОВАТЬ для конструктора
Ниже код работает:
Редактировать для RTM
Вам необходимо зарегистрироваться
IHttpContextAccessor
:источник
ClaimTypes.NameIdentifier
дает текущий идентификатор пользователя иClaimTypes.Name
дает имя пользователя.null
в моем случае?.Net core 2.1 Web api
Хотя я использую .Простой способ, который работает, и я проверил.
тогда вы можете все свойства этой переменной как
user.Email
. Надеюсь, это кому-то поможет.Редактировать :
Это очевидно простая вещь, но немного сложная причина различных типов систем аутентификации в ASP.NET Core. Я обновляю, потому что некоторые люди получают
null
.Для аутентификации JWT (проверено на ASP.NET Core v3.0.0-preview7):
источник
Есть другой способ получить текущего пользователя в Asp.NET Core - и я думаю, что видел его где-то здесь, на SO ^^
Этот код переходит в контроллер с именем DemoController. Не будет работать без обоих await (не компилируется);)
источник
Я должен сказать, что был очень удивлен, что HttpContext имеет значение null внутри конструктора. Я уверен, что это из соображений производительности. Подтвердили, что при использовании,
IPrincipal
как описано ниже, он вводится в конструктор. По сути, он делает то же самое, что и принятый ответ, но более интерфейсным способом.Для тех, кто нашел этот вопрос и ищет ответ на общий вопрос «Как получить текущего пользователя?» вы можете просто получить доступ
User
прямо изController.User
. Но вы можете делать это только внутри методов действий (я предполагаю, потому что контроллеры работают не только с HttpContexts и по соображениям производительности).Однако - если вам это нужно в конструкторе (как это сделал OP) или вам нужно создать другие инъекционные объекты, которым нужен текущий пользователь, то ниже будет лучший подход:
Внедрить IPrincipal, чтобы получить пользователя
Первая встреча
IPrincipal
иIIdentity
IPrincipal
иIIdentity
представляет пользователя и имя пользователя. Википедия утешит вас, если «Директор» звучит странно .Важно понимать, что независимо от того, получаете ли вы это
IHttpContextAccessor.HttpContext.User
,ControllerBase.User
илиControllerBase.HttpContext.User
вы получаете объект, который гарантированно являетсяClaimsPrincipal
объектом, который реализуетIPrincipal
.В настоящее время ASP.NET не использует другого типа пользователя
User
(но это не значит, что что-то другое не может реализоватьIPrincipal
).Поэтому, если у вас есть что-то, что зависит от «текущего имени пользователя», которое вы хотите ввести, вы должны вводить,
IPrincipal
а определенно нетIHttpContextAccessor
.Важно: не тратьте время на инъекции
IPrincipal
непосредственно в ваш контроллер или метод действия - это бессмысленно, посколькуUser
оно уже доступно вам там.В
startup.cs
:Затем в вашем объекте DI, которому нужен пользователь, которого вы просто вводите,
IPrincipal
чтобы получить текущего пользователя.Самым важным здесь является то, что если вы выполняете модульные тесты, вам не нужно отправлять
HttpContext
, а нужно только имитировать то, что представляет собой то,IPrincipal
что может бытьClaimsPrincipal
.Еще одна важная вещь, в которой я не уверен на 100%. Если вам нужно получить доступ к фактическим заявкам от
ClaimsPrincipal
вас, необходимо преобразовать ихIPrincipal
вClaimsPrincipal
. Это нормально, поскольку мы на 100% знаем, что во время выполнения он относится к этому типу (раз уж онHttpContext.User
есть). На самом деле мне нравится просто делать это в конструкторе, поскольку я уже точно знаю, что любой из нихIPrincipal
будетClaimsPrincipal
.Если вы делаете насмешку, просто создайте файл
ClaimsPrincipal
напрямую и передайте его всем, что нужноIPrincipal
.IClaimsPrincipal
Я не уверен, почему именно для этого нет интерфейса . Я предполагаю, что MS решила, чтоClaimsPrincipal
это просто специализированная «коллекция», для которой не нужен интерфейс.источник
null
за уколIPrincipal
. Мне также нужно было добавить временную службу как…GetService<IHttpContextAccessor>()?.HttpContext.User…
(с?
), потому что в противном случае она вылетела бы из строя (GetService вернул значение null).services.AddTransient(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
как HttpContext.User - это ClaimsPrincipal.Похоже, что на данный момент (апрель 2017 года) работает следующее:
По крайней мере, в пределах
Controller
источник
=>
оператор использовался таким образом, он называется «Определение тела выражения» и описан в этой документации . На всякий случай будущие люди вроде меня задаются вопросом.IIdentity
вstring
, как также указано в верхнем комментарии. Редакция просто исправила это. Я также не уверен, как вы пришли к своему выводу (в частности, поскольку «редакторские» баллы начисляются только пользователям с репутацией ниже 2к).Возможно, я не видел ответа, но я так делаю.
Вам необходимо изменить эти значения
Startup.cs -> ConfigureServices (...)
MVC или веб-контроллер API
Метод контроллера:
Результат - имя пользователя, например = Домен \ имя пользователя
источник
Моя проблема заключалась в том, чтобы получить доступ к зарегистрированному пользователю как объекту в файле cshtml. Учитывая, что вам нужен пользователь во ViewData, этот подход может быть полезным:
В файле cshtml
источник
В дополнение к существующим ответам я хотел бы добавить, что у вас также может быть экземпляр класса, доступный для всего приложения, который содержит данные, связанные с пользователем, например
UserID
и т. Д.Это может быть полезно для рефакторинга, например вы не хотите получать
UserID
в каждом действии контроллера и объявлять дополнительныйUserID
параметр в каждом методе, относящемся к уровню обслуживания.Я провел исследование и вот мой пост .
Вы просто расширяете свой класс, от которого вы производите
DbContext
, добавляяUserId
свойство (или реализуя собственныйSession
класс, у которого есть это свойство).На уровне фильтра вы можете получить экземпляр класса и установить
UserId
значение.После этого куда бы вы ни внедрили свой экземпляр - у него будут необходимые данные (время жизни должно быть на запрос , поэтому вы регистрируете его с помощью
AddScoped
метода).Рабочий пример:
Для получения дополнительной информации см. Мой ответ .
источник
Взять
IdentityUser
тоже подойдет. Это текущий пользовательский объект, и все значения пользователя могут быть получены.источник
Если вы используете scafolded Identity и Asp.net Core 2.2+, вы можете получить доступ к текущему пользователю из следующего вида:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio
источник
Это старый вопрос, но мой случай показывает, что мой случай здесь не обсуждался.
Больше всего мне нравится ответ Simon_Weaver ( https://stackoverflow.com/a/54411397/2903893 ). Он подробно объясняет, как получить имя пользователя с помощью IPrincipal и IIdentity. Это абсолютно правильный ответ, и я рекомендую использовать этот подход. Однако во время отладки я столкнулся с проблемой, когда ASP.NET НЕ может правильно заполнить принцип службы . (или, другими словами, IPrincipal.Identity.Name имеет значение null)
Очевидно, что для получения имени пользователя MVC-фреймворк должен откуда-то его взять. В мире .NET ASP.NET или ASP.NET Core используют промежуточное ПО Open ID Connect. В простом сценарии веб-приложения аутентифицируют пользователя в веб-браузере. В этом сценарии веб-приложение указывает браузеру пользователя выполнить вход в Azure AD. Azure AD возвращает ответ на вход через браузер пользователя, который содержит утверждения о пользователе в токене безопасности. Чтобы он работал в коде вашего приложения, вам необходимо предоставить полномочия, которым ваше веб-приложение делегирует вход. При развертывании веб-приложения в службе Azure обычно выполняется настройка веб-приложения: «Службы приложений» -> Ваше приложение -> колонка «Аутентификация / авторизация» -> «Проверка подлинности службы приложений» = «Вкл.»https://github.com/Huachao/azure-content/blob/master/articles/app-service-api/app-service-api-authentication.md ). Я полагаю (это мое обоснованное предположение), что под капотом этого процесса мастер настраивает «родительскую» веб-конфигурацию этого веб-приложения, добавляя те же настройки, которые я показываю в следующих абзацах. По сути, проблема, почему этот подход НЕ работает в ASP.NET Core, заключается в том, что конфигурация «родительской» машины игнорируется webconfig. (я не уверен на 100%, я просто даю лучшее объяснение, которое у меня есть). Итак, чтобы заставить его работать, вам нужно настроить это вручную в своем приложении.
Вот статья, в которой объясняется, как многократно настроить приложение для использования Azure AD. https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2
Шаг 1. Зарегистрируйте образец в своем клиенте Azure AD. (это очевидно, не хочу тратить свое время на объяснения).
Шаг 2. В файле appsettings.json: замените значение ClientID идентификатором приложения из приложения, которое вы зарегистрировали на портале регистрации приложений на шаге 1. Замените значение TenantId общим
Шаг 3. Откройте файл Startup.cs и в методе ConfigureServices после строки, содержащей .AddAzureAD, вставьте следующий код, который позволяет вашему приложению входить в систему пользователей с конечной точкой Azure AD v2.0, то есть рабочей и учебной и Личные учетные записи Microsoft.
Резюме : я показал еще одну возможную проблему, которая может привести к ошибке, в которой объясняется тема для начала. Причина этой проблемы - отсутствие конфигурации для Azure AD (промежуточное ПО Open ID). Для решения этой проблемы предлагаю вручную настроить «Аутентификацию / Авторизацию». Добавлен краткий обзор того, как это настроить.
источник
Большинство ответов показывают, как лучше всего справиться
HttpContext
с документацией, что я тоже сделал.Я хотел упомянуть, что вы захотите проверить настройки проекта при отладке, по умолчанию это
Enable Anonymous Authentication = true
.источник
Я получил свое решение
источник