2015-04-13 2 views
0

Я использую 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 вопрос (в одном):

  1. Как действительно ли я подтверждаю, что picketlink сохраняет роли, которые я назначаю пользователям, которых я создаю?
  2. Где в базе данных (или в другом месте) находятся эти назначенные роли, которые я могу подтвердить?
  3. Если я проверяю роли пользователей неправильно (см. Мой код), как мне исправить это?
+0

Qs 1 & 2 в стороне, есть ли причина, по которой вы не можете выполнить то, что хотите, используя стандартные аннотации Java EE? См. [Javax.annotation.security] (http://docs.oracle.com/javaee/7/api/javax/annotation/security/package-summary.html). –

+0

@SteveC, спасибо за альтернативы, но основная причина, по которой я использую роли PL, заключается в том, что у меня есть требование управлять распределением и назначением ролей с использованием базовой модели PL - в принципе, должно быть возможно сопоставить эти роли с PL пользователя и группы, запрашивать и выполнять операции CRUD. Итак, я должен работать с PL. Но я также попытаюсь изучить эту альтернативу, если все остальное не удастся. – nemesisfixx

+0

WildFly уже использует PicketLink под капотом, чтобы реализовать то, что вы повторно реализуете. –

ответ

0

После консультации с другом. Я внедрил следующую реализацию аннотации безопасности, которая работает, как ожидалось:

package com.dsmagic.satex.auth; 

import com.dsmagic.satex.annotations.BasicRolesAllowed; 
import org.apache.deltaspike.security.api.authorization.Secures; 
import org.jboss.logging.Logger; 
import org.picketlink.Identity; 
import org.picketlink.idm.IdentityManager; 
import org.picketlink.idm.RelationshipManager; 
import org.picketlink.idm.model.basic.BasicModel; 
import org.picketlink.idm.model.basic.Role; 
import org.picketlink.idm.model.basic.User; 

import javax.enterprise.context.ApplicationScoped; 
import javax.interceptor.InvocationContext; 

@ApplicationScoped 
public class Authorizer { 

    Logger log = Logger.getLogger(Authorizer.class); 

    @Secures 
    @BasicRolesAllowed 
    public boolean isBasicRolesAllowed(InvocationContext invocationContext, Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) { 

     boolean isUserAllowed = false; 

     if (identity != null && identity.isLoggedIn() && identity.getAccount() != null) 
     { 
      User user = BasicModel.getUser(identityManager, ((User)identity.getAccount()).getLoginName()); 
      log.info(String.format("-------- Role-Checking for User: %s", user.getLoginName())); 

      if (invocationContext.getMethod().isAnnotationPresent(BasicRolesAllowed.class)) 
      { 
       BasicRolesAllowed basicRolesAllowed = invocationContext.getMethod().getAnnotation(BasicRolesAllowed.class); 

       for (int i = 0; i < basicRolesAllowed.value().length; i++) 
       { 
        Role role = BasicModel.getRole(identityManager, basicRolesAllowed.value()[i]); 

        if (user != null && role != null) 
        { 
         if (BasicModel.hasRole(relationshipManager, user, role)) 
         { 
          isUserAllowed = true; 
          break; 
         }else 
          log.info(String.format("-------- Doesn't have ROLE: %s", role.getName())); 
        } 

       } 
      } 
     } 


     return isUserAllowed; 
    } 

} 

Надеюсь, это тоже поможет кому-то еще.

Смежные вопросы