Как изменить парадигму безопасности для MembershipProvider? - PullRequest
2 голосов
/ 13 июля 2009

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

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

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

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

<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, должен иметь Просмотр прав на бизнес-объект Person .

У меня уже есть объект Authorizer с такой подписью:

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

Что будет принимать, например, тип Person, доступ View (enum) и пользователя для проверки. Теперь у меня есть код внутри авторизации разобрался.

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

Ответы [ 2 ]

1 голос
/ 14 июля 2009

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

  • просмотр | Персона
  • Редактировать | Персона
  • добавить | Перон

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

  • A
  • A | B или A | C или A | D

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

Предложение

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

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

Теперь вы скрыли тот факт, что это строка полностью.

1 голос
/ 14 июля 2009

Я нашел довольно простой способ решить мою проблему. Я изменил подпись Authorize, чтобы она принимала перечисление вместо типа, и использую его в 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);
}

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

void Page_Load(...)
{
    if (Context.User.IsInRole(AuthorizationType.Person + '|' + Access.View)
    {
        //I have view rights, do some stuff
    }   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...