Используя ASP Членство.NET и Профиль с MVC, как я могу создать пользователя и установить его на HttpContext. Текущий. Пользователь?

Я реализовал пользовательский объект Профиля в коде, как описано Joel здесь:

Как присвоить значения Профиля?

Я не могу заставить это работать, когда я создаю нового пользователя, как бы то ни было. Когда я делаю это:

Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");

пользователь создается и добавляется к роли в базе данных, но HttpContext.Current.User все еще пусто, и Membership.GetUser() пустой указатель возвратов, таким образом, это (из кода Joel) не работает:

static public AccountProfile CurrentUser
{
    get { return (AccountProfile)
                     (ProfileBase.Create(Membership.GetUser().UserName)); }
}

AccountProfile.CurrentUser.FullName = "Snoopy";

Я попытался звонить Membership.GetUser(userName) и свойства установки Profile тот путь, но свойства набора остается пустым, и вызов AccountProfile.CurrentUser(userName).Save() ничего не помещает в базу данных. Я также попытался указать, что пользователь действителен и вошел в систему путем вызова Membership.ValidateUser, FormsAuthentication.SetAuthCookie, и т.д., но текущий пользователь является все еще пустым или анонимным (в зависимости от состояния моих cookie браузера).

РЕШЕННЫЙ (ОТРЕДАКТИРОВАННЫЙ ДАЛЕЕ, ПОСМОТРИТЕ НИЖЕ): На основе объяснения Franci Penov и еще некоторого экспериментирования, я выяснил проблему. Код Joel и изменения, которые я попробовал, будут только работать с существующим Профилем. Если никакой Профиль не существует, ProfileBase.Create(userName) возвратит новый пустой объект каждый раз, когда это называют; можно установить свойства, но они не будут "придерживаться", потому что новый экземпляр возвращается каждый раз, когда Вы получаете доступ к нему. Установка HttpContext.Current.User к новому GenericPrincipal даст Вам Пользовательский объект, но не объект Профиля, и ProfileBase.Create(userName) и HttpContext.Current.Profile все еще укажет на новые, пустые объекты.

Если Вы хотите создать Профиль для недавно созданного Пользователя в том же запросе, необходимо звонить HttpContext.Current.Profile.Initialize(userName, true). Можно затем заполнить инициализированный профиль и сохранить его, и это будет доступно по будущим запросам по имени, таким образом, код Joel будет работать. Я только использую HttpContext.Current.Profile внутренне, когда я должен создать/получить доступ Профиль непосредственно после создания. По любым другим запросам я использую ProfileBase.Create(userName), и я выставил только ту версию как общественность.

Обратите внимание, что Franci корректен: Если Вы будете готовы создать Пользователя (и Роли) и установить его как Аутентифицируемый на первом распространении в прямом и обратном направлениях и попросить, чтобы пользователь затем вошел в систему, то Вы сможете получить доступ к Профилю очень проще с помощью кода Joel последующего запроса. То, что бросило меня, - то, что Роли сразу доступны после пользовательского создания без любой инициализации, но Профиль не.

Мой новый код AccountProfile:

public static AccountProfile CurrentUser
{
    get
    {
        if (Membership.GetUser() != null)
            return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
        else
            return null;
    }
}

internal static AccountProfile NewUser
{
    get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}

Новое пользовательское создание:

MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();

Последующий доступ:

if (Membership.ValidateUser(userName, password))
{
    string name = AccountProfile.CurrentUser.FullName;
}

Далее благодаря Franci для объяснения жизненного цикла Аутентификации - я называю FormsAuthentication. SetAuthCookie в моей функции проверки, но я возвращаю bool для указания на успех, потому что Пользователь. Идентификационные данные. IsAuthenticated не будет верен до последующего запроса.

ПЕРЕСМОТРЕННЫЙ: я - идиот. Вышеупомянутое объяснение работает в узком случае, но не разрешает базовую проблему: Вызов CurrentUser возвращает новый экземпляр объекта каждый раз, является ли это существующим Профилем или нет. Поскольку это определяется как свойство, я не думал об этом и записал:

AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();

который (конечно), не работает. Это должно быть:

AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();

Это - мой собственный отказ для того, чтобы полностью пропустить этот основной пункт, но я действительно думаю, объявляя CurrentUser, поскольку свойство подразумевает, что это - объект, которым можно управлять. Вместо этого это должно быть объявлено как GetCurrentUser().

17
задан Community 23 May 2017 в 12:24
поделиться

1 ответ

Создание пользователя просто добавляет его в список пользователей. Однако это не аутентифицирует и не авторизует нового пользователя для текущего запроса. Вам также необходимо аутентифицировать пользователя в контексте текущего запроса или для последующих запросов.

Membership.ValidateUser только подтверждает учетные данные, но не аутентифицирует пользователя для текущего или последующих запросов. FormsAuthentication.SetAuthCookie установит билет аутентификации в поток ответа, так что следующий запрос будет аутентифицирован, но это не влияет на состояние текущего запроса.

Самым простым способом аутентификации пользователя был бы вызов FormsAuthentication.RedirectFromLoginPage (если вы используете аутентификацию форм в своем приложении). Однако этот вызов фактически вызовет новый HTTP-запрос, в результате которого пользователь будет аутентифицирован.

В качестве альтернативы, если вам нужно продолжить логику обработки текущего запроса, но вы хотите, чтобы пользователь был аутентифицирован, вы можете создать GenericPrincipal, присвоить ему идентификатор нового пользователя и установить HttpContext.User на этого принципала.

7
ответ дан 30 November 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: