Поддерживает ли модель безопасности Java EE ACL? - PullRequest
8 голосов
/ 31 августа 2010

Я использовал Java EE 6 с Glassfish v3.0.1, и мне интересно, поддерживает ли модель безопасности Java EE ACL, и если да, то насколько она детализирована?

EDITED
Я реализую Безопасность, используя область jdbc через glassfish v3, чтобы область во время выполнения изучала таблицу USER внутри базы данных, чтобы проверить аутентификацию, взглянув на поле password и авторизацию, взглянув на поле role. Поле ролей содержит только 2 либо ADMINISTRATOR, либо DESIGNER. Так что это взаимно-однозначная карта между пользователем и ролью. На уровне управляемого компонента я реализовал это

private Principal getLoggedInUser()
{
    HttpServletRequest request =
            (HttpServletRequest) FacesContext.getCurrentInstance().
                getExternalContext().getRequest();
    if(request.isUserInRole("ADMINISTRATORS")){
        admin = true;
    }else{
        admin = false;
    }
    return request.getUserPrincipal();
}

public boolean isUserNotLogin()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser == null)
    {
        return true;
    }
    return false;
}

public String getLoginUserName()
{
    Principal loginUser = getLoggedInUser();
    if (loginUser != null)
    {
        return loginUser.getName();
    }
    return "None";
} 

позвонив по номеру isUserInRole, я могу определить, является ли пользователь admin или нет, тогда JSF render изменит содержимое соответствующим образом. Однако, это недостаточно детально (очень быстрая справочная информация: существует несколько проектов, проект содержит несколько чертежей). Потому что, если вы DESIGNER, вы можете видеть все чертежи из всех проектов (что если я хочу, чтобы tom работал только над проектом A, тогда как peter будет работать над проектом B, Cindy может руководить двумя проектами A и B). Я хочу, чтобы во время выполнения, когда я создавал пользователя, я мог конкретно указать, какой проект он / она может видеть. Есть ли способ сделать это? ПРИМЕЧАНИЕ. Существует более двух проектов, приведенный выше пример только для демонстрации .

Ответы [ 2 ]

5 голосов
/ 31 августа 2010

Модель безопасности Java EE аутентифицирует «принципала», который может иметь одну или несколько «ролей».

В другом измерении у вас есть службы и ресурсы, для которых требуются настраиваемые «Разрешения» или «Возможности».

В конфигурации вы определяете, какие «Принципы» или «Роли» имеют какие «Разрешения» или «Возможности».

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

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

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

SELECT p.* FROM projects p, assignments a WHERE p.id = a.projectId AND a.finishdate < NOW();

или

@Stateless class SomeThing {

    @Resource SessionContext ctx;

    @RolesAllowed("DESIGNER")
    public void doSomething(Project project) {
        String userName = ctx.getCallerPrincipal.getName();

        if (project.getTeamMembers().contains(userName) {
            // do stuff
        }
    }

}

Обратите внимание, что грубый контроль доступа здесь был сделан с аннотацией вместо кода. Это может значительно усложнить тестирование шаблона и сэкономить много времени.

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

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

Во многих реализациях JSF есть теги, которые могут помочь отрисовывать необязательные вещи. Вот примеры для richfaces и seam:

<!-- richfaces -->
<rich:panel header="Admin panel" rendered="#{rich:isUserInRole('admin')}">
  Very sensitive information
</rich:panel>

<!-- seam -->
<h:commandButton value="edit" rendered="#{isUserInRole['admin']}"/>.

Вот статья , объясняющая, как добавить ее в ADF

4 голосов
/ 31 августа 2010

Модель безопасности Java EE реализует RBAC (управление доступом на основе ролей).Для программиста Java EE это фактически означает, что пользователям могут быть предоставлены разрешения на доступ к ресурсу.Ресурсы могут включать файлы, базы данных или даже код.Следовательно, можно не только ограничить доступ к объектам, таким как файлы и таблицы в базах данных, но также можно ограничить доступ к исполняемому коду.

Теперь разрешения могут быть сгруппированы в роли, которые в конечном итоге связаны спользователи / субъекты.Вкратце, это модель безопасности Java EE.

Из описания вашей проблемы видно, что вы хотите различать два разных проекта как два разных ресурса и, следовательно, иметь либо два отдельных объекта разрешения, либо дваотдельные роли для учета одинаковы.Учитывая, что у вас уже есть роли (более подходящие для этого как группы пользователей), такие как Администратор, Дизайнер и т. Д., Это не может быть достигнуто довольно легко в Java EE.Причина в том, что вы различаете доступ к ресурсам для пользователей в роли, основываясь на дополнительном свойстве ресурса - идентификаторе проекта.Технически это относится к области, известной как ABAC (управление доступом на основе атрибутов).

Одним из способов достижения ABAC в Java EE является передача свойств / атрибутов, предоставленных роли, в имени роли.Поэтому вместо следующего кода:

if(request.isUserInRole("DESIGNERS")){
    access = true;
}else{
    access = false;
}

вы должны сделать что-то вроде следующего.Обратите внимание на символ «:», используемый в качестве разделителя, чтобы отличить имя роли от сопровождающего атрибута.

if(request.isUserInRole("DESIGNERS"+":"+projectId)){
    access = true;
}else{
    access = false;
}

Конечно, есть часть, где ваш модуль входа в систему должен быть изменен (либо в конфигурации, либо в коде) возвращать роли, содержащие идентификаторы проектов, а не простые имена ролей.Обратите внимание, что все эти предлагаемые изменения должны быть всесторонне рассмотрены на наличие проблем - например, следует запретить использование символа разделителя в качестве части имени роли, в противном случае вполне возможно выполнять атаки на повышение привилегий.

Если реализация вышеприведенного окажется немного полезной, вы можете взглянуть на такие системы, как Shibboleth , которые обеспечивают поддержку ABAC, хотя я никогда не видел, чтобы это использовалось в приложении Java EE.

...