Как использовать Ext JS для ролевого приложения

Я планирую использовать Ext JS для большого приложения. Функции приложения основаны на ролях. При входе в систему они видят только связанные с ними функции меню и экрана. Моя технология на стороне сервера будет Java и JSP.

Чтобы решить это, у меня есть две идеи.
  1. Создайте Javascript, связанный с JS JS, динамически после входа пользователя с использованием технологии на стороне сервера. Сервлет /JSP создаст необходимый код est js в соответствии с ролями пользователя.

  2. Имейте Js-переменные, которые заданы в порядке JSP, которые будут использоваться для обеспечения только правильных функций, доступных пользователям.

Каков наилучший способ обеспечения безопасности и предоставления пользовательского интерфейса на основе ролей в приложении Ext Js.
Спасибо заранее за ваши идеи..

Абдель Олакара

Ответы

Ответ 1

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

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

Я обнаружил, что есть несколько способов сделать это, но есть, в частности, два подхода, которые являются самыми разумными. Независимо от подхода, есть две вещи, которые следует учитывать: 1) какой JavaScript для сервера и как избежать ненужной логики, и 2) как избежать выполнения логики, недоступной для пользователя.

Конфигурация ленивых загрузок и разрешений:

  • Все виджеты в моем приложении ленивы загружаются через dojo.require, поэтому не нужно беспокоиться о ненужном включении JavaScript, который не был применим к пользователю. Я не очень хорошо знаком с библиотекой ExtJs, но, насколько я видел, он не дает сопоставимого метода; однако важно, чтобы синхронный вызов ajax сопровождался eval. В любом случае в этом методе важно, чтобы функциональность компонента не пересекалась через разные файлы (также, как правило, это хороший дизайн). Каждый файл должен быть его собственным классом, который управляет определенным виджетами или другим элементом пользовательского интерфейса.

  • Затем я устанавливаю разрешения в созданном сервером классе JavaScript. Затем этот класс может ссылаться во всем приложении на то, что есть и что не разрешено.

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

com.project.frontController.prototype.init = function(widgets) {
   var permissions = com.project.config.permissions;

   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If access is restricted to the widget (by id), then disable it.
       if ( !permissions[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

И config выглядел примерно так:

com.project.config.permissions = {
    "widgetAbc": {
        btnAccessNode:     "#some-css-selector",
        otherWidgetConfig: "etc"
    },
    "widgetXyz": {
        btnAccessNode:     "div.some-css-selector"
    }
};

Проверка компиляции и функциональности:

  • Некоторые приложения скомпилируют весь свой JavaScript в один файл, а затем передадут его клиенту. Если ваше приложение делает такую ​​вещь, и вы можете это сделать динамически, все необходимые JS можно определить на стороне сервера, прежде чем он будет обслуживаться. Конечно, это наберет некоторые издержки; однако вы можете кэшировать скомпилированные версии по ролям. Если роли немного, то этот кеш может быть легко загрунтован, и это просто вопрос включения одного конкретного script.

  • Поскольку доступен только разрешенный JavaScript, просто обнаружив, что доступный класс/функция доступен, прежде чем пытаться выполнить его, все, что вам нужно сделать для проверки прав доступа.

Например, включение script может выглядеть так:

<script type="text/javascript" src="/js/compiler.php?role=moderator"></script>

И ваша проверка работоспособности будет выглядеть примерно так:

com.project.frontController.prototype.init = function(widgets) {
   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If the widget controller doesn't exist, disable it.
       if ( !com.project.util.widgetExists[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

или

com.project.someWidget.prototype.launchOtherWidget = function() {
    if ( typeof otherWidget != "undefined" ) {
        (new otherWidget()).open();
    }
};

Обратите внимание, что оба метода очень похожи в реализации. Я бы сказал, что лучший способ сделать выбор между ними - это рассмотреть размер вашей кодовой базы, инструменты, доступные вам для компиляции "на лету", и кэшировать эти скомпилированные пакеты на основе ролей. Для моего проекта не только компилятор не был доступен в среде, но база кода была большой (1.3mb завышена /296kb по умолчанию плюс библиотека dojo), что было неприемлемо, так как клиент больше интересовался поддержанием низких время загрузки приложения.

Ответ 2

В нашей компании jsp загружает объект конфигурации, созданный сервером на основе роли текущего пользователя. Затем клиентская сторона отображает эту конфигурацию.

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

Ответ 3

Всегда применяйте защиту на стороне сервера, скрывая элементы управления в интерфейсе, которого недостаточно.
ИЗМЕНИТЬ
На стороне клиента? хорошо, вы можете следить за любыми советами в других ответах, но верно, что пользователь может выполнять произвольный javascript, изменять страницу DOM и делать любой запрос, который он хочет.

Ответ 4

Не доставляйте клиенту функциональность, которую пользователь не может видеть. Вы можете загружать js файлы динамически, но ваш сервер приложений должен применять ваши правила; нет роли, нет JS.

  var jsFile = document.createElement('script');
  jsFile.setAttribute( "type", "text/javascript" );
  jsFile.setAttribute( "src", 'someFileName.js' );
  document.getElementsByTagName("head")[0].appendChild(jsFile);

Вы можете использовать LDAP или более простое решение на стороне сервера, но (опять же) не обслуживать JS для пользователей, которые не имеют права на это. На клиенте проверьте наличие класса (во время разработки создайте один класс для JS файла) и не пытайтесь создать объект, когда его класс не загружен.