Я использую Picketlink (2.6.0.Final) с JPA (используя Postgresql) для сохранения. Я также осуществил инициализатору со следующей основой:Где пользовательские роли хранятся в таблицах picketlink при использовании JPA?
@Singleton
@Startup
public class Initialiser {
@Inject
private PartitionManager partitionManager;
// Create users
@PostConstruct
public void createUsers()
{
try {
createUser("admin", new String[]{RoleConstants.BASIC});
} catch (Exception ex) {} // Ignore error
try {
createUser("paul", new String[]{RoleConstants.BASIC, RoleConstants.IS_ADMIN});
} catch (Exception ex) {} // Ignore error
}
private void createUser(String loginName, String[] roles)
{
User user = new User(loginName);
IdentityManager identityManager = this.partitionManager.createIdentityManager();
identityManager.add(user);
identityManager.updateCredential(user, new Password(loginName + "Test"));
for (String role: roles) {
Role xrole = new Role(role);
identityManager.add(xrole);
RelationshipManager relationshipManager = this.partitionManager.createRelationshipManager();
grantRole(relationshipManager, user, xrole);
}
}
}
После развертывания моей war
в Wildfly, я действительно вижу, что мои пользователи создаются в указанной базе данных PostgreSQL - в accounttypeentity
таблицы. И я могу запросить и найти эти учетные записи пользователей, используя обычный подход JPA (через поиск IdentityQuery
).
Проблема:
Я использую PL, чтобы обеспечить мой RESTful API (реализована с использованием JAX-RS), и они, как я это сделал? Оформление каждой конечной точки пользовательской аннотацией, предназначенной для проверки того, имеет ли вызывающий объект конечной точки сеанс входа в систему и имеет ли дочерняя учетная запись пользователя необходимые роли (каждая конечная точка передает требуемые роли как часть аннотации).
Проблема в том, что даже когда у меня есть вход в систему - identity.isLoggedIn() == true
, и даже когда этот пользователь является одним из тех, которые я создал при инициализации с требуемыми ролями, вызов, чтобы проверить, имеет ли этот пользователь какой-либо из требуемые роли не удались! Существенный код:
hasRole(relationshipManager, user, getRole(identityManager, role)
И все определение пользовательских аннотаций является:
@ApplicationScoped
public class CustomAuthorizer {
Logger log = Logger.getLogger(CustomAuthorizer.class);
@Inject
Identity identity;
@Inject
IdentityManager identityManager;
@Inject
RelationshipManager relationshipManager;
/**
* This method is used to check if classes and methods annotated with {@link BasicRolesAllowed} can perform
* the operation or not
*
* @param identity The Identity bean, representing the currently authenticated user
* @param identityManager The IdentityManager provides methods for checking a user's roles
* @return true if the user can execute the method or class
* @throws Exception
*/
@Secures
@BasicRolesAllowed
public boolean hasBasicRolesCheck(InvocationContext invocationContext) throws Exception {
log.error("** Checking roles...");
BasicRolesAllowed basicRolesAllowed = getAnnotation(invocationContext,BasicRolesAllowed.class);
String[] requiredRoles = basicRolesAllowed.value();// get these from annotation
Identity identity = getIdentity();
if((requiredRoles.length > 0) && (!getIdentity().isLoggedIn()))
{
log.error("** User Not Logged In: can't pass role checking...");
return false;
}
boolean isAuthorized = true;
User user = (User) getIdentity().getAccount();
for (String role : requiredRoles) {
isAuthorized = isAuthorized && hasRole(relationshipManager, user, getRole(identityManager, role));
log.info(String.format("User:%s | Role: %s | Has?: %s", user, role, isAuthorized));
}
return isAuthorized;
}
private <T extends Annotation> T getAnnotation(InvocationContext invocationContext, Class<T> annotationType) {
Class unproxiedClass = getUnproxiedClass(invocationContext.getTarget().getClass());
T annotation = (T) unproxiedClass.getAnnotation(annotationType);
Method invocationContextMethod = invocationContext.getMethod();
if (annotation == null) {
annotation = invocationContextMethod.getAnnotation(annotationType);
}
if (annotation == null) {
throw new IllegalArgumentException("No annotation [" + annotationType + " found in type [" + unproxiedClass + "] or method [" + invocationContextMethod + ".");
}
return annotation;
}
private Identity getIdentity() {
return this.identity;
}
}
Итак, я буду обманывать немного и ставлю на 3 вопрос (в одном):
- Как действительно ли я подтверждаю, что picketlink сохраняет роли, которые я назначаю пользователям, которых я создаю?
- Где в базе данных (или в другом месте) находятся эти назначенные роли, которые я могу подтвердить?
- Если я проверяю роли пользователей неправильно (см. Мой код), как мне исправить это?
Qs 1 & 2 в стороне, есть ли причина, по которой вы не можете выполнить то, что хотите, используя стандартные аннотации Java EE? См. [Javax.annotation.security] (http://docs.oracle.com/javaee/7/api/javax/annotation/security/package-summary.html). –
@SteveC, спасибо за альтернативы, но основная причина, по которой я использую роли PL, заключается в том, что у меня есть требование управлять распределением и назначением ролей с использованием базовой модели PL - в принципе, должно быть возможно сопоставить эти роли с PL пользователя и группы, запрашивать и выполнять операции CRUD. Итак, я должен работать с PL. Но я также попытаюсь изучить эту альтернативу, если все остальное не удастся. – nemesisfixx
WildFly уже использует PicketLink под капотом, чтобы реализовать то, что вы повторно реализуете. –