FormsAuthentication использует один и тот же билет во всех браузерах (на одном компьютере)? - PullRequest
1 голос
/ 24 апреля 2011

Я не понимаю, что происходит с FormsAuthentication.Когда я впервые включаю свой компьютер и начинаю работать над своим проектом, каждый раз, когда я пытаюсь войти в систему, я получаю сообщение об ошибке, сообщающее, что запрашиваемое имя пользователя (в моем случае это псевдоним) не находит последовательность.Я проверяю его значение во время отладки, получается, что это пустая строка ("").Затем, если я прекращаю отладку, затем запускаю ее снова, я вхожу в систему нормально, и он выбирает правильное имя пользователя.

Более того, если я пытаюсь войти в систему с другим пользователем из другого браузера, происходит то же самое, но в конечном итоге этовыбирает того же пользователя, который вошел в систему с помощью того же браузера!Использует ли FormsAuthentication один и тот же билет во всех браузерах для всех пользователей?Что я могу с этим поделать?Или может быть, я здесь что-то не так делаю ...?

Вот мой код:

    [HttpPost]
    public ActionResult Login(LoginViewModel dto)
    {  
        bool flag = false;
        if (ModelState.IsValid)
        {
            if (_userService.AuthenticateUser(dto.Email, dto.Password, false))
            {
                var user = _userService.GetUserByEmail(dto.Email);

                flag = true;

                FormsAuthentication.SetAuthCookie(user.Nickname, dto.RememberMe);
            }
        }
        if (flag)
        {
            return RedirectToAction("Index", "Home");
        }
        else
        {
            ViewData.Add("InvalidLogin", "The login info you provided were incorrect.");
            return PartialView(dto);
        }
    }

    public User GetUserFromSession(bool withAllInfo)
    {
        string nickname = _httpContext.User.Identity.Name;
        IsNotNull(nickname, "session user nickname");
        var user = _userService.GetUserByNickname(nickname, withAllInfo);
        return user;
    }

    public User GetUserFromSession(string nickname, bool withAllInfo)
    {
        if (string.IsNullOrEmpty(nickname))
            return GetUserFromSession(withAllInfo);

        var user = _userService.GetUserByNickname(nickname, withAllInfo);
        return user;
    }

Вышеприведенный метод находится во вспомогательном классе (который принимает экземпляр HttpContext- используя StructureMap).Он продолжает возвращать пользователя с псевдонимом J.Smith, даже если я вошел в систему с другим пользователем.И забавно то, что он затем отображает правильно вошедшего в систему пользователя с помощью Summary ActionMethod (см. Ниже).

    [Authorize]
    public ActionResult Summary()
    {
        var nickname = this.HttpContext.User.Identity.Name;
        var user = _helper.GetUserFromSession(nickname, true);
        var viewModel = Mapper.Map<User, UserInfoSummaryViewModel>(user);
        return PartialView(viewModel);
    }

Этот метод отображает сводку всей информации пользователя, включая его ставки, списки,новые сообщения ... и т. д. Это на самом деле работает правильно (в большинстве случаев).Но проблема в методе GetUserFromSession(), который все портит.

    public ActionResult SignOut()
    {
        FormsAuthentication.SignOut();
        return RedirectToAction("Index", "Home");
    }

Это все, что мне нужно сделать, чтобы выйти из системы и удалить его cookie / сеанс или что-то еще, что FormsAuthentication делает для управления сеансами?

Примечание. Я не использую встроенный API-интерфейс для членства и не хочу его использовать.

Итак, что я могу сделать, чтобы исправить этот беспорядок?

ОБНОВЛЕНИЕ:

Конфигурация StructureMap:

    private static IContainer ConfigureStructureMap()
    {

        ObjectFactory.Configure(x =>
                            {
                                x.For<IDatabaseFactory>().Use<EfDatabaseFactory>();
                                x.For<IUnitOfWork>().Use<UnitOfWork>();
                                x.For(typeof (IRepository<>)).Use(typeof (BaseRepository<>));
                                x.For<IGenericMethodsRepository>().Use<GenericMethodsRepository>();
                                x.For<IUserService>().Use<UsersManager>();
                                x.For<IBiddingService>().Use<BiddingService>();
                                x.For<ISearchService>().Use<SearchService>();
                                x.For<IFaqService>().Use<FaqService>();
                                x.For<IItemsService>().Use<ItemsService>();
                                x.For<IPrivateMessagingService>().Use<PrivateMessagingService>();
                                x.For<IStaticQueriesService>().Use<StaticQueriesService>();
                                x.For<ICommentingService>().Use<CommentingService>();
                                x.For<ICategoryService>().Use<CategoryService>();
                                x.For<IHelper>().Use<Helper>();
                                x.For<HttpContext>().Use(HttpContext.Current);

            x.For(typeof(Validator<>)).Use(typeof(NullValidator<>));

            x.For<Validator<Rating>>().Use<RatingValidator>();
            x.For<Validator<TopLevelCategory>>().Use<TopLevelCategoryValidator>();
        });

        Func<Type, IValidator> validatorFactory = type =>
        {
            var valType = typeof(Validator<>).MakeGenericType(type);
            return (IValidator)ObjectFactory.GetInstance(valType);
        };

        ObjectFactory.Configure(x => x.For<IValidationProvider>().Use(() => new ValidationProvider(validatorFactory)));
        return ObjectFactory.Container;
    }

Ответы [ 2 ]

0 голосов
/ 24 июня 2011

Вы можете написать класс (интерфейс) провайдера HttpContext, который просто возвращает текущий экземпляр HttpContext.Current.

using System.Web;

interface IHttpContextProvider
{
    HttpContextBase HttpContext { get; }
}

public class HttpContextProvider : IHttpContextProvider
{
    HttpContextBase HttpContext
    {
        get
        {
            return new HttpContextWrapper(System.Web.HttpContext.Current);
        }
    }
}
0 голосов
/ 25 апреля 2011

Похоже, что область для экземпляра _httpContext, который поддерживается / создается StrucutureMap, неверна. Вот немного больше информации о сфере действия - я был бы рад изучить ее подробнее, если вы хотите опубликовать свой регистрационный код StrucutureMap.

...