Как создать подкласс BasicPermission для добавления действий

1

Я хочу создать подкласс BasicPermission для добавления действий, которые в соответствии с java-документами должны быть возможны:

При необходимости подклассы могут выполнять действия поверх BasicPermission.

Вот моя первоначальная попытка:

public class BasicPermissionWithActions extends BasicPermission {

String        actions;
String[]      actionList;
String        name;

public BasicPermissionWithActions(String name, String actions) {
    super(name, actions);
    this.actions = actions;
    this.actionList = actions.split("\\,");
    this.name = name;
}

private static final long serialVersionUID = 7608854273379948062L;

@Override
public boolean implies(Permission p) {
    // name and class check can be done by super
    if (!super.implies(p))
        return false;

    // now check actions
    String requestedActions = p.getActions();
    String[] requestedActionList = requestedActions.split("\\,");
    for (String requestedAction : requestedActionList) {
        if (!hasRequestedAction(requestedAction))
            return false;
    }

    return true;
}

private boolean hasRequestedAction(String requestedAction) {
    for (String action : actionList) {
        if (action.equals(requestedAction))
            return true;
    }
    return false;
}

@Override
public String getActions() {
    return actions;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + ((actions == null) ? 0 : actions.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (!super.equals(obj))
        return false;
    if (getClass() != obj.getClass())
        return false;
    BasicPermissionWithActions other = (BasicPermissionWithActions) obj;
    if (actions == null) {
        if (other.actions != null)
            return false;
    } else if (!actions.equals(other.actions))
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

@Override
public String toString() {
    return "(\"" + this.getClass().getName() + "\" \"" + name + "\" \"" + actions + "\")"; 
}

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

grant principal sample.principal.SampleGroup "TestGroup" {
  permission BasicPermissionWithActions "*", "read";
};

И код для проверки разрешения:

        rep.getAccessControlContext().checkPermission(new BasicPermissionWithActions(getName(), "write"));

Я ожидаю, что эта проверка завершится неудачей, так как политика указала только действие чтения. Однако чек проходит спокойно.

Проблема в том, что всякий раз, когда разрешение в файле политики имеет имя "*", действия никогда не проверяются. Запуск в режиме отладки показывает, что метод BasicPermissionWithActions.implies не вызывается.

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

Теги:
permissions
security
jaas

1 ответ

2
Лучший ответ

Проблема связана с PermissionCollection. BasicPermission реализует собственный PermissionCollection для лучшей производительности. К сожалению, эта реализация делает некоторые упрощающие предположения, которые нарушают семантику для подклассов. В частности, он реализует ярлык для "*", который обходит метод Permission.implies и всегда возвращает true.

Решение заключается в реализации пользовательского PermissionCollection, который просто вызывает методы Permission.implies своих членов:

    private class CustomPermissionCollection extends PermissionCollection {

    private static final long serialVersionUID = 5654758059940546018L;

    Collection<Permission> perms = new ArrayList<Permission>();

    @Override
    public void add(Permission permission) {
        perms.add(permission);
    }

    @Override
    public boolean implies(Permission permission) {
        for (Permission p : perms) {
            if (p.implies(permission))
                return true;
        }
        return false;
    }

    @Override
    public Enumeration<Permission> elements() {
        return Collections.enumeration(perms);
    }

}

и вернуть это в метод newPermissionCollection BasicPermissionWithActions

@Override
public PermissionCollection newPermissionCollection() {
    return new CustomPermissionCollection();
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню