Я создал приложение клиент/сервер с помощью JAAS. Вход в систему работает нормально, так как вход в систему успешен. Именно при попытке предоставить разрешения определенным методам AccessController
начинает приводить AccessControlException
.
java.security.AccessControlException: access denied ("myPackage.CustomPermission" "someMethod")
Класс разрешения:
public class CustomPermission extends BasicPermission {
public CustomPermission(String name) {
super(name);
}
public CustomPermission(String name, String method) {
super(name, method);
}
}
У меня также есть собственный основной класс:
public class CustomPrincipal implements Principal {
private String name;
public CustomPrincipal(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
При входе пользователь указывает имя пользователя и пароль. В БД имена пользователей и пароли имеют связанный с ними «уровень пользователя». Эти пользовательские уровни используются в качестве имен-участников, добавляемых к Subject
, созданному при входе в систему. Я добавляю его при обработке commit
-метода в LoginModule
:
public boolean commit() throws LoginException {
if(status == ConfigValues.NOT || subject == null)
return false;
principal = new CustomPrincipal(userlvl);
if(subject.getPrincipals().add(principal)) {
username = null;
password = null;
status = ConfigValues.COMMIT;
return true;
}
return false;
}
Ради этого я создаю процедуру входа в систему следующим образом:
LoginContext lc = new LoginContext("MyLoginModule", new RemoteCallbackHandler(username, password));
lc.login();
new ServerImpl(lc.getSubject());
Затем Subject
используется в реализации «прокси-сервера» для проверки разрешений, например так (user = lc.getSubject
):
public String someMethod() throws RemoteException, PrivilegedActionException {
return Subject.doAs(user, new PrivilegedExceptionAction<String>() {
@Override
public String run() throws PrivilegedActionException, RemoteException, ServerNotActiveException {
AccessController.checkPermission(new CustomPermission("someMethod"));
return realServerImplObj.someMethod();
}
});
}
.policy-файл:
grant codeBase "file:./bin/-" Principal myPackage.CustomPrincipal "user" {
permission myPackage.CustomPermission "someMethod";
};
«Пользователь», конечно же, является одним из уровней пользователя, с которым вы можете войти в систему.
Я попытался добавить дополнительные гранты, например:
grant codeBase "file:./bin/-" {
permission javax.security.auth.AuthPermission "createLoginContext.MyLoginModule";
permission javax.security.auth.AuthPermission "doAs";
};
У меня также есть конфигурация для LoginModule:
MyLoginModule {
myPackage.MyLoginModule required debug=true;
};
Я установил свойства перед всем этим, конечно: редактировать: файлы расположены в корне проекта
System.setProperty("java.security.auth.login.config", "file:./MyConfig.config");
System.setProperty("java.security.policy", "file:./MyPolicy.policy");
Сервер запускается с аргументом -Djava.security.manager
. Клиент не использует какие-либо аргументы, файлы конфигурации или политики.
Я попытался удалить codeBase, чтобы убедиться, что мой путь неверен. Если я добавлю permissions java.util.AllPermissions
, то все в порядке (но... конечно, это не хорошо, так как это определенно не так, как задумано). Что я делаю неправильно здесь? Я предполагаю, что это комбинация реализации Principal-, Permission, .policiy- и LoginModule.
РЕДАКТИРОВАТЬ Исключение вызывается при вызове AccessController.checkPermissions(...)
в реализации "прокси-сервера".
РЕДАКТИРОВАТЬ 2 Я пробовал следующее редактирование кода:
return AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
@Override
public String run() throws PrivilegedActionException, RemoteException, ServerNotActiveException {
//AccessController.checkPermission(new CustomPermission("someMethod"));
return realServerImplObj.someMethod();
}
});
Обратите внимание, что я изменил Subject.doAs(user, new Privile....
на AccessController.doPrivileged(new Privilege
. user
больше не анализируется в параметре, и мы используем статический метод AccessController.doPrivileged
, а не Subject.doAs
. Еще одно примечание: //AccessController.checkPermission(new CustomPer...
был прокомментирован.
Но теперь каждый может вызывать любой метод, поскольку мы фактически никогда не проверяем разрешения. Это как если бы AccessController никогда не знал о разрешениях, предоставленных в файле .policy.
РЕДАКТИРОВАТЬ 3 Казалось, проблема связана с реализацией Принципала.
Просто для уточнения, вот какие изменения были внесены:
@Override
public String someMethod() throws PrivilegedActionException {
return Subject.doAsPrivileged(user, new PrivilegedExceptionAction<String>() {
@Override
public String run() throws PrivilegedActionException, RemoteException, ServerNotActiveException {
AccessController.checkPermission(new CustomPermission("someMethod"));
return realServerImplObj.someMethod();
}
}, null);
}
Разница return Subject.doAsPrivileged(user, ... , null);
. Обратите внимание на ноль в конце.
Реализовано два метода в классе CustomPrincipal
, #equals(Object)
и #hashCode()
. См. здесь можно найти универсальный пример обоих методов и образец Principal
реализации в целом.
Также добавлено (хотя на самом деле кажется, что оно работает без) следующее: файл .policy
grant codeBase "file:./bin/-" {
permission javax.security.auth.AuthPermission "createLoginContext.MyLoginModule";
permission javax.security.auth.AuthPermission "doAs";
permission javax.security.auth.AuthPermission "doAsPrivileged";
};
permission javax.security.auth.AuthPermission "doAsPrivileged";
— новая добавленная запись.
AuthPermission("doAsPrivileged")
файлу:./bin/- и подставитьSubject.doAs
вместоSubject.doAsPrivileged(..., null)
. - person Uux   schedule 24.11.2016Subject.doAsPrivileged(...,null)
наSubject.doAs
- это то, что я на самом деле имел в виду выше. - person Uux   schedule 24.11.2016doAsPrivileged
также принимает 3 параметра:(Subject, PrivilegedAction<T>, AccessControlContext)
. Я пробовал с помощью doAsPrivileged параметры(user, null, AccessController.getContext)
. Я не понимаю, чего вы пытаетесь достичь, делая это (игнорируя мои предыдущие заметки; допустим, это было возможно). Можете ли вы уточнить? - person eli   schedule 24.11.2016Subject#doAsPrivileged(yourUser, yourAction, null)
. Здесь важно значениеnull AccessControlContext
, поскольку оно эффективно настраиваетPermission
s кадра стека после вызоваdoAsPrivileged
на точно те, которые были предоставленыyourUser
. Обратите внимание: приведет ли это к повышению или снижению привилегий, зависит исключительно от того, какиеyourUser
были предоставлены на уровнеPolicy
. - person Uux   schedule 24.11.2016Principal
реализует#hashCode()
и#equals(Object)
. - person Uux   schedule 24.11.2016Policy
(sun.security.provider.PolicyFile
), которая в отсутствиеPrincipal#equals
не может проверить, что активныйPrincipal
эквивалентен тому, что в егоgrant
утверждениях . Можете ли вы объяснить, что вы подразумеваете под дополнительными разрешениями? Каким будет их ожидаемый набор разрешений? Что им на самом деле дают? - person Uux   schedule 24.11.2016AccessController.checkPermission
. В основном никаких проверок разрешений не проводилось. ;-) Можешь ответить? Я проголосую + установим его как правильный ответ, так как он работает сейчас. - person eli   schedule 24.11.2016