Как использовать AspNetSqlMembershipProvider для нескольких одновременных сессий? - PullRequest
1 голос
/ 06 декабря 2011

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

Я использую MVC3 с AspNetSqlMembershipProvider для авторизации \ аутентификации.

Как я могу легко использовать несколько одновременных входов в систему на одном компьютере?

Ответы [ 3 ]

2 голосов
/ 06 декабря 2011

Вы должны абстрагировать это на более высоком уровне, чем аутентифицированный пользователь. Я предлагаю вам представить концепцию зарегистрированного пользователя и текущего пользователя. Сеанс остается с вошедшим в систему пользователем, но вошедшие в систему пользователи с достаточными привилегиями имеют возможность выдавать себя за других пользователей, причем этот пользователь становится текущим пользователем. Использовать текущего пользователя для управления доступом к данным, управлять пользовательским интерфейсом (за исключением того, что пользователю, имитирующему себя, необходимо контролировать олицетворение), выполнять транзакции и т. Д. Сохранять текущего пользователя в сеансе в качестве данных, возможно, устанавливая часто используемые свойства в базовый контроллер в OnActionExecuting по мере необходимости.

public class AdminController : BaseController
{

    [Authorize( Roles = "ActOnBehalfOfUser" )]
    [AcceptVerbs( HttpVerbs.Get )]
    public ActionResult Impersonate()
    {
        return View();
    }

    [Authorize( Roles = "ActOnBehalfOfUser" )]
    [AcceptVerbs( HttpVerbs.Post )]
    [ValidateAntiForgeryToken]
    public ActionResult Impersonate( string userNameOrID, bool? revoke )
    {
        var currentUser = this.GetCurrentUser();

        if (revoke.HasValue && revoke.Value)
        {
            try
            {
                LogImpersonationEnd( currentUser );
            }
            catch { }
            this.SetEffectiveUser( currentUser );
        }
        else
        {
            if (string.IsNullOrEmpty( userNameOrID ))
            {
                this.ModelState.AddModelError( "userNameOrID", "You must supply a username or uid to impersonate." );
                return View();
            }

            var person = this.LookupUser( userNameOrID );
            if (person == null)
            {
                this.ModelState.AddModelError( "userNameOrID", "No user with the given id was found." );
                return View();
            }

            this.SetEffectiveUser( person );
            try
            {
                using (var dc = new FooDataContext())
                {
                    var impersonation = new Impersonation
                    {
                        EffectiveUser = person.UID,
                        ActualUser = currentUser.UID
                    };
                    dc.InsertOnSubmit( impersonation );
                    dc.SubmitChanges();
                }
            }
            catch { }
        }

        return View();

    }
}

Базовый контроллер:

public class BaseController : Controller
{
    protected bool IsImpersonating
    {
        get
        {
            var effectiveUID = this.Session[EFFECTIVE_USER_KEY] as string;
            var uid = this.Session[USER_KEY] as string;
            return !string.Equals( effectiveUID, uid );
        }
    }

    protected Person GetEffectiveUser()
    {
        return GetUser( this.Session[EFFECTIVE_USER_KEY] as string );
    }

    protected void SetEffectiveUser( Person person )
    {
        this.Session[EFFECTIVE_USER_KEY] = person.UniversityID;
        this.Session[UIPERSON_KEY + person.UniversityID] = person;
    }

    protected Person GetUser( string uid )
    {
        Person person = null;
        if (!string.IsNullOrEmpty( uid ))
        {
            person= GetCachedPerson( uid, p => p.UID == uid );
        }
        return person ?? new AnonymousPerson();
    }



    protected Person LookupUser( string usernameOrUID )
    {
        Person person = null;
        if (!string.IsNullOrEmpty( usernameOrUID ))
        {
            uiPerson = this.GetCachedPerson( usernameOrUID, p => p.UID== usernameOrUID || p.Username == usernameOrUID );
        }
        return uiPerson;
    }

    private Person GetCachedPerson( string uid, Expression<Func<Person, bool>> selector )
    {
        Person person = this.Session[PERSON_KEY + uid] as Person;
        if (person == null)
        {
            using (var context = new FooDataContext())
            {
                person = context.SingleOrDefault<Person>( selector );
                if (uiPerson != null)
                {
                    this.Session[PERSON_KEY + uid] = person;
                }
            }
        }
        return person;
    }

    protected void LogImpersonationEnd( Person currentUser )
    {
        using (var dc = new FooDataContext())
        {
            var euid = this.GetEffectiveUser().UID;
            var impersonation = dc.Table<Impersonation>()
                                  .Where( i => i.EffectiveUser == euid && i.ActualUser == currentUser.UniversityID && !i.EndTime.HasValue )
                                  .OrderByDescending( i => i.ID )
                                  .FirstOrDefault();

            if (impersonation != null)
            {
                impersonation.EndTime = DateTime.Now;
                dc.SubmitChanges();
            }
        }
    }
}
1 голос
/ 06 декабря 2011

Поскольку членство в ASP.NET работает с использованием файлов cookie, не существует простого программного решения, о котором я знаю. Однако вы можете сделать так, чтобы служба поддержки входила в другой браузер (например, IE и Firefox). Или, если вы управляете настройкой сайта, вы можете указать другой URL-адрес для поддержки: support.domain.com против www.domain.com, чтобы файл cookie отличался.

0 голосов
/ 06 декабря 2011

Самым простым решением было бы заставить пользователей службы поддержки войти в систему как пользователь в другом браузере, например, войти в систему как в IE, но как в Chrome

...