2009-07-13 3 views
2

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

У меня есть собственный IPrincipal, IIdentity и MembershipProvider. У меня аутентификация работает нормально. Проблема, с которой я столкнулся сейчас, - это авторизация.

Проблема, которую я имею с помощью схемы авторизации, наследуется в поведении IsInRole от IPrincipal. Такое поведение тесно связано с различными функциями ASP.NET Webforms, и моя главная задача заключается в авторизации сайта, потому что я бы хотел использовать его, если смогу.

Таким образом, вы, возможно, традиционно есть карта сайта, как так:

<siteMap xmlns="blahblah"> 
    <siteMapNode url="PersonView.aspx" 
     title="View Person" 
     description="View the details of a person" 
     roles="ViewerRole" /> 
</siteMap> 

Здесь потребуется, кто пытается перейти на страницу PersonView.aspx иметь ViewerRole. Здесь возникает моя проблема. Я не хочу, чтобы мое разрешение было привязано к роли пользователя. Вместо этого я хочу, чтобы авторизация была привязана к поведению, которое я выполняю, и пусть некоторые основные вещи за кулисами позаботятся о авторизации.

Так что я действительно хочу что-то вроде этого, вместо:

<siteMap xmlns="blahblah"> 
    <siteMapNode url="PersonView.aspx" 
     title="View Person" 
     description="View the details of a person" 
     roles="Person|View" /> 
</siteMap> 

Это должно быть истолковано как тех, кто пытается перейти на страницу PersonView.aspx должны Просмотр права на Человек бизнес-объекта ,

У меня уже есть объект Авторизатор, который имеет подпись, как так:

public static bool Authorize(Type type, Access access, IUser user) 

который будет принимать, например, тип личности, вид доступа (перечисление), и пользователю проверить его против. Теперь у меня есть код внутри авторизации.

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

ответ

1

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

  • вид | Человек
  • Редактировать | Person
  • надстройку | Peron

как три разные роли. Я видел, как это использовалось в системе, которая имела иерархию функций, поэтому у вас может быть Feature A -> Feature B, C или D, например, где BC и D могут существовать только в том случае, если у вас есть A. Тогда это могут быть роли, такие как :

  • | B или А | с или А | D

Так что теперь ваш код может проверить, если они А или, если вам нужно проверить subfeature вы можете проверить A | B ,

Предложение

Чтобы сделать осущ еще лучше в вашей загрузки страницы Что делать, если вы сделали:

if (Context.User.IsInRole(
     PermissionFactory.CreateToken(AuthorizationType.Person,Access.View))) 
{   
    //I have view rights, do some stuff  
} 

Теперь вы скрытом тот факт, что это строка укомплектовать.

+0

Спасибо за ваше предложение. Джош, мне нравится идея иметь PermissionFactory, чтобы изолировать генерацию магической строки. Однако генерация маркера не была бы действительно полезной в файле Sitemap. Как вы относитесь к файлам Sitemap в этом сценарии? Держите их магическими струнами? – Joseph

+0

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

+0

@ Josh Да, мне нужно бороться с ним целиком, потому что моя парадигма принципиально отличается. Это очень раздражает. – Joseph

1

Я выяснил довольно чистый способ решить мою проблему. То, что я сделал, это изменить мою подпись авторизации, чтобы принять перечисление вместо типа, и использовать это в IsInRole для определения разрешения.

Так у меня есть:

public static bool Authorize(AuthorizationType type, Access access, IUser user) 

, а затем я использую его в IsInRole так:

public bool IsInRole(string role) 
{ 
    var typeAndAccess = role.Split('|'); 
    var authType = 
     (AuthorizationType)Enum.Parse(
      typeof(AuthorizationType), typeAndAccess[0]); 
    var access = (Access)Enum.Parse(typeof(Access), typeAndAccess[1]); 

    return Authorizer.Authorize(
     authType, access, Context.User.Identity as IUser); 
} 

Это позволяет мне использовать волшебную струнный подход, когда я абсолютно необходимо (например, в sitemap), но это также позволяет мне более строго типизированный подход, когда я использую его программно:

void Page_Load(...) 
{ 
    if (Context.User.IsInRole(AuthorizationType.Person + '|' + Access.View) 
    { 
     //I have view rights, do some stuff 
    } 
} 
Смежные вопросы