Возможно ли иметь более одного участника в ASP.NET?

Недавно мне дали задание создать отдельный логин для пользователей, которые принадлежат к определенной роли. Вход уже был реализован для основных пользователей, и это было сделано с использованием принципала, который был назначен Thread.CurrentPrincipal и позже проверяется на значение каждый раз при загрузке страницы. Я изменил свой код, чтобы использовать тот же механизм аутентификации, поэтому в моем пользовательском входе в систему я создаю пользовательского Принципала и назначаю его Thread.CurrentPrincipal. Теперь проблема в том, что при настраиваемом входе в систему я переопределяю свой обычный вход и наоборот. Можно ли назначить мой принцип где-нибудь еще, кроме Thread.CurrentPrincipal, чтобы оба варианта входа работали одновременно? Если это невозможно, я хотел бы узнать об альтернативах :)


person Denis Vitez    schedule 29.09.2015    source источник
comment
Что вы подразумеваете под отдельным логином? Что вы имеете в виду, говоря, что я отменяю свой обычный логин?   -  person Serg Rogovtsev    schedule 29.09.2015
comment
Вы имеете в виду, что хотите, чтобы ваше приложение позволяло, например, аутентификацию на основе утверждений и форм?   -  person Dbuggy    schedule 29.09.2015
comment
Вы вообще не должны изменять принцип потока, хранить свою информацию аутентификации в объекте сеанса или в файле cookie. Если вы хотите, чтобы он был более безопасным, сохраните только зашифрованный ключ аутентификации и найдите принцип для аутентифицированных пользователей в базе данных или другом хранилище данных. ASP.net имеет встроенных провайдеров аутентификации, которые вы должны попробовать использовать.   -  person Ron Beyer    schedule 29.09.2015
comment
Под отдельным входом я подразумеваю, что к некоторым контроллерам можно получить доступ с помощью первого типа входа, в то время как к другим можно получить доступ с помощью моего пользовательского типа входа. Вход в систему осуществляется с использованием разных учетных данных пользователя (пароль, PIN-код, ...) и с использованием разных форм. Переопределив мой обычный вход в систему, я имел в виду, что если я вхожу в систему как обычный пользователь, а затем вхожу через свой собственный вход, Thread.Principle переопределяется моим пользовательским принципом, и поэтому основной вход в систему больше не действителен. Итак, я могу предположить, что существующий логин с Thread.Principle - плохая практика, и я должен попытаться реализовать свою аутентификацию с помощью сеанса или cookie?   -  person Denis Vitez    schedule 29.09.2015
comment
@RonBeyer Изменение участника потока - очень распространенная и допустимая практика, например, при использовании настраиваемого объекта участника безопасности. Хранение информации аутентификации в сеансе или в файле cookie не делает ее доступной для базового поставщика. Это просто позволяет сохранять его между страницами.   -  person DVK    schedule 29.09.2015
comment
@DVK stackoverflow.com/questions/3057937/   -  person Ron Beyer    schedule 29.09.2015


Ответы (2)


Это очень выполнимо и не очень сложно. Лучший способ, который я нашел для этого, - реализовать собственный IPrincipal, у которого есть свойство, которое также содержит IPrincipal. Затем вы можете сохранить оба объекта в потоке и реализовать метод IsInRole таким образом, чтобы можно было проверять оба объекта-участника для целей авторизации. Какой-то псевдокод ...

public class MyPrincipal : IPrincipal
{
    public IPrincipal FormsPrincipal { get; private set; }

    public MyPrincipal(IPrincipal formsPrincipal)
    {
        FormsPrincipal = formsPrincipal;
    }

    public bool IsInRole(string role)
    {
        if (someCondition)
        {
            // check roles for this
        }
        else
        {
            return FormsPrincipal.IsInRole(role); // check role against the other principal
        }
    }
}

Затем в PostAuthenticateRequest используйте текущего участника для создания нового настраиваемого участника и назначьте его в качестве участника HttpContext.Current.

Хороший ресурс с большим количеством деталей: ASP.NET MVC - Установите пользовательский IIdentity или IPrincipal

person DVK    schedule 29.09.2015
comment
Я создал CustomPrinciple, который содержит два моих объекта IPrinciple. У меня были некоторые проблемы с его правильной работой, но похоже, что теперь он работает. Спасибо за ваш anwser @DVK. - person Denis Vitez; 30.09.2015

Ответ от DVK действителен, но в прошлом у меня были сложности при использовании пользовательских IPrincipals. Альтернативный подход - использовать одного участника, представленного ClaimsPrincipal, и использовать тот факт, что он может хранить несколько идентификаторов. Затем вы можете использовать, например, реализации по умолчанию IsInRole.

https://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal(v=vs.110).aspx

person Mike Goodwin    schedule 29.09.2015