Будут ли статические публичные переменные в моем приложении использоваться совместно с другими пользователями в том же приложении? - PullRequest
0 голосов
/ 11 ноября 2010

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

Вот мои настройки:

PageHttpModule.cs - это добавляется в web.config как httpModule.

public class PageHttpModule : IHttpModule
{
    public void Init(HttpApplication app)
    {
        app.AuthenticateRequest += new EventHandler(OnAuthenticateRequest);
    }

    public void OnAuthenticateRequest(Object s, EventArgs e)
    {
         CurrentUser.Initialize();
    }

    public void Dispose() { }
}

CurrentUser.cs

public static class CurrentUser
{
  public static bool IsAuthenticated { get; private set; }
  public static string Email {get; set;}
  public static string RealName {get; set;
  public static string UserId {get; set;}

    public static void Initialize()
    {
        CurrentUser.AuthenticateUser();
    }


    Note: this is a scaled down version of my authentication code.

    public static void AuthenticateUser()
    {
        UserAuthentication user = new UserAuthentication();
        user.AuthenticateUser();

        if (user.IsAuthenticated)
        {
            CurrentUser.IsAuthenticated = true;
            CurrentUser.UserId = user.UserId;
            CurrentUser.Email = user.Email;
            CurrentUser.RealName = user.RealName;
        }
     }
}

UserAuthentication.cs

public class UserAuthentication
{

    public string Email { get; set; }
    public string RealName { get; set; }
    public string UserId { get; set; }
    public bool IsAuthenticated { get; private set; }

    public UserAuthentication()
    {
        IsAuthenticated = false;
        Email = String.Empty;
        RealName = String.Empty;
        UserId = String.Empty;
    }

    public void AuthenticateUser()
    {

        //do some logic here.. if the user is ok then 
        IsAuthenticated = true
        Email = address from db
        UserId = userid from db;
        Realname = name from db;
   }
}

Я проверил между 3 различными браузерами, и, кажется, работает нормально, но я все еще учусь и не хочусовершить огромную ошибку.

Если моя логика полностью неверна, то как мне это сделать, чтобы мне не приходилось размещать пользовательские запросы на каждой странице напрямую?

Ответы [ 4 ]

3 голосов
/ 11 ноября 2010

Нет, это не потокобезопасно.Для экземпляров приложения, находящихся в отдельных процессах или доменах приложений, это будет просто замечательно.Но если ваш сервер ASP.NET будет обслуживать несколько запросов одновременно, используя многопоточность, у вас будут очень серьезные побочные эффекты, если два человека попытаются использовать приложение одновременно.

1 голос
/ 11 ноября 2010

В методе Init параметр HttpApplication описывается следующим образом:

HttpApplication, обеспечивающий доступ к методам, свойствам и событиям, общим для всех объектов приложения в ASP.NET-приложение

Ключевым моментом здесь является то, что существует один PageHttpModule для времени жизни приложения, и все статические объекты, которые существуют во время жизни приложения, будут совместно использовать эти переменные.

НО ... время жизни CurrentUser находится только в пределах события OnAuthenticateRequest, если только какая-либо другая ссылка не поддерживает объект живым.Если бы это была PageHttpModule переменная уровня участника, у вас были бы проблемы, которые вы бы сразу заметили.В вашей ситуации, однако, вы будете работать нормально , если не получите более одного одновременно обработанного OnAuthenticateRequest вызова .

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

Обновление Я думаю, что часть проблемы связана с неправильным пониманием AuthenticateRequest ... К тому времени, когда это событие вызывается, пользователь уже прошел проверку подлинности с помощью проверки подлинности Windows или Forms ... вы просто получаете уведомление о том, что это произошло,На самом деле свойство User.Identity.IsAuthenticated уже установлено (я думаю, что это событие срабатывает, даже если пользователь не проходит аутентификацию, но я не буду клясться в этом без двойной проверки).

Если я понимаю, что выпосле, вы действительно пытаетесь написать свой собственный поставщик членства.Если вы воспользуетесь этим подходом, вы получите все преимущества встроенной аутентификации ... все стандартные свойства, связанные с аутентификацией, будут установлены и доступны и будут изолированы для сеанса пользователя так, как вы хотите.

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

Попытка полностью переписать механизм аутентификации будет прыгать через болезненные, сложные обходы.

Некоторые ссылки:http://www.devx.com/asp/Article/29256/0/page/3http://www.codeproject.com/KB/aspnet/WSSecurityProvider.aspxhttp://msdn.microsoft.com/en-us/library/f1kyba5e%28v=VS.90%29.aspx

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

1 голос
/ 11 ноября 2010

Почему бы просто не сделать то, что рекомендует Microsoft?

http://msdn.microsoft.com/en-us/library/9wff0kyh.aspx

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


Вот еще одна ссылка, которая должна оказаться полезной:

http://blogs.msdn.com/b/ncl/archive/2009/05/05/custom-http-authentication-schemes.aspx

0 голосов
/ 11 ноября 2010

То, что вы сделали с IHttpModule, кажется хорошим способом решения этой проблемы.Одна из целей http-модуля, заявленная Microsoft, состоит в том, чтобы включить любой вид специальной аутентификации.Когда модуль http инициализируется, он использует тот же экземпляр для новых запросов.Так как у вас нет глобальных переменных, я не уверен, как ответить на вопрос, безопасный для вашего потока.Кажется, вы только читаете некоторые данные, поэтому, пожалуйста, уточните!

...