java - 自定义 IDM 身份验证和授权者

标签 java authorization picketlink

我有 Picketlink IDM JPA 身份验证模型的自定义实现。我通过处理那里的一个例子得到了它https://github.com/jboss-developer/jboss-picketlink-quickstarts/tree/master/picketlink-idm-custom-identity-model打包 org.picketlink.idm.jpa.model.custom.simple。然后我实现了这个例子https://github.com/pedroigor/picketlink-quickstarts/tree/master/picketlink-deltaspike-authorization 。 我在 picketlink-idm-custom-identity-model 示例中更改了 User 类和 UserTypeEntity,如下所示:

@IdentityStereotype(USER)
public class User extends AbstractIdentityType implements Account {
  public static final QueryParameter USER_NAME = QUERY_ATTRIBUTE.byName("userName");
  @StereotypeProperty(IDENTITY_USER_NAME)
  @AttributeProperty
  @Unique
  private String userName;
  @AttributeProperty
  private String firstName;
  @AttributeProperty
  private String lastName;
  @AttributeProperty
  private String email;
  @AttributeProperty
  private String middleName;
  @AttributeProperty
  private String telephone;
  @AttributeProperty
  private String address;
  @AttributeProperty
  private int postIndex;
  @AttributeProperty
  private Date registerDate;
  @AttributeProperty
  private Date lastVisitDate;
  @AttributeProperty
  private boolean isOrganizer;
  @AttributeProperty
  private boolean isAdmin;
  @Embedded
  private Organizer organizer;
  @Embedded
  private Customer customer;
  // getters and setters
}

class UserTypeEntity

  @IdentityManaged(User.class)
  @Entity
  public class UserTypeEntity extends AbstractIdentityTypeEntity {
  @AttributeValue
  private String userName;
  @OwnerReference
  @ManyToOne(fetch = FetchType.LAZY)
  private RealmTypeEntity realm;
  @AttributeProperty
  private String firstName;
  @AttributeProperty
  private String lastName;
  @AttributeProperty
  private String email;
  @AttributeProperty
  @Column(length = 255)
  private String middleName;
  @AttributeProperty
  @Size(max = 12)
  @Column(length = 12)
  private String telephone;
  @AttributeProperty
  @Column(length = 5000)
  @Size(max = 5000)
  private String address;
  @AttributeProperty
  private int postIndex;
  @AttributeProperty
  private Date registerDate;
  @AttributeProperty
  private Date lastVisitDate;
  @AttributeProperty
  private boolean isOrganizer;
  @AttributeProperty
  private boolean isAdmin;
  @Embedded
  private Organizer organizer;
  @Embedded
  private Customer customer;
  // getters and setters
}

然后我实现了登录 Controller :

@Named
@Stateless
public class LoginController {
  @Inject
  private Identity identity;
  @Inject
  private FacesContext facesContext;
  public void login() {
    AuthenticationResult result = identity.login();
    if (AuthenticationResult.FAILED.equals(result)) {
      facesContext.addMessage(
          null,
          new FacesMessage("Invalid user name or password"));
    }
  }
}

和注册 Controller :

@Named
@RequestScoped
public class RegistrationController {
  private IdentityManager identityManager;
  @Inject
  private PartitionManager partitionManager;
  @Inject
  private FacesContext facesContext;
  @Inject
  private User user;
  private String password;
  private String passwordVerify;
  private boolean isOrganizer;
  public RegistrationController() {
  }
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }
  public String getPasswordVerify() {
    return passwordVerify;
  }
  public void setPasswordVerify(String passwordVerify) {
    this.passwordVerify = passwordVerify;
  }
  public boolean getIsOrganizer() {
    return isOrganizer;
  }
  public void setIsOrganizer(boolean isOrganizer) {
    this.isOrganizer = isOrganizer;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  @Transactional
  public String register() throws Exception {
    if (password.isEmpty()) {
      String message = LocaleBean.loadErrorMessage(facesContext, LocaleBean.EX_RESOURCE_BUNDLE_NAME, "password.empty");
      facesContext.addMessage("signup:registrationPassword", new FacesMessage(message));
      return "returnToSignup";
    }
    if (!password.equals(passwordVerify)) {
      String message = LocaleBean.loadErrorMessage(facesContext, LocaleBean.EX_RESOURCE_BUNDLE_NAME, "password.NotEqual");
      facesContext.addMessage("signup:registrationPassword", new FacesMessage(message));
      return "returnToSignup";
    }
      identityManager = partitionManager.createIdentityManager(partitionManager.getPartition(Realm.class,
          Resources.REALM_ACME_NAME));
      if (isOrganizer) {
        user.setOrganizer(true);
        user.setOrganizer(new Organizer());
        try {
          identityManager.add(user);
        } catch (IdentityManagementException e) {
          String message = LocaleBean.loadErrorMessage(facesContext, LocaleBean.EX_RESOURCE_BUNDLE_NAME, "login.Registered");
          facesContext.addMessage(null, new FacesMessage(message));
          return "returnToSignup";
        }
        Password password = new Password(this.password);
        identityManager.updateCredential(user, password);
        RelationshipManager relationshipManager = partitionManager.createRelationshipManager();
        IdentityQuery<Group> query = identityManager.createIdentityQuery(Group.class);
        // query all childs of sales unit
        query.setParameter(Group.NAME, Resources.ORGANIZERS_GROUP_NAME);
        List<Group> groups = query.getResultList();
        Group organizersGroup = groups.get(0);
        relationshipManager.add(new GroupMembership(user, organizersGroup));
      } else {
      }
    return "signin";
  }
}

之后我实现了授权者:

@ApplicationScoped
public class SPAuthorizer {
  @Secures
  @Admins
  public boolean doAdminsCheck(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) throws Exception {
    return hasGroup(identity, identityManager, relationshipManager, Resources.ADMINS_GROUP_NAME);
  }
  @Secures
  @Organizers
  public boolean doOrganizersCheck(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) throws Exception {
    return hasGroup(identity, identityManager, relationshipManager, Resources.ORGANIZERS_GROUP_NAME);
  }
  @Secures
  @Customers
  public boolean doCustomersCheck(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) throws Exception {
    return hasGroup(identity, identityManager, relationshipManager, Resources.CUSTOMERS_GROUP_NAME);
  }
  private boolean hasGroup(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager,
                           String groupName) {
    IdentityQuery<Group> queryGroup = identityManager.createIdentityQuery(Group.class);
    // query all childs of sales unit
    queryGroup.setParameter(Group.NAME, groupName);
    List<Group> groups = queryGroup.getResultList();
    if (groups.size() == 1) {
      Group group = groups.get(0);
      Account user = identity.getAccount();
      if (user == null) {
        return false;
      }
      RelationshipQuery<GroupMembership> query = relationshipManager.createRelationshipQuery(GroupMembership.class);
      query.setParameter(GroupMembership.GROUP, group);
      query.setParameter(GroupMembership.MEMBER, user);
      // user is assigned with two groups
      List<GroupMembership> resultList = query.getResultList();
      return resultList.size() > 0;
    }
    return false;
  }
}

所以我实现了授权检查器来检查 JSF 中某个组的所属用户:

@Named
@Stateless
public class AuthorizationChecker {
  @Inject
  private Identity identity;
  @Inject
  private PartitionManager partitionManager;
  public boolean hasGroup(String groupName) {
    IdentityManager identityManager = partitionManager.createIdentityManager(partitionManager.getPartition(Realm.class,
        Resources.REALM_ACME_NAME));
    IdentityQuery<Group> queryGroup = identityManager.createIdentityQuery(Group.class);
    // query all childs of sales unit
    queryGroup.setParameter(Group.NAME, groupName);
    List<Group> groups = queryGroup.getResultList();
    if (groups.size() == 1) {
      Group group = groups.get(0);
      Account user = identity.getAccount();
      RelationshipManager relationshipManager = partitionManager.createRelationshipManager();
      RelationshipQuery<GroupMembership> query = relationshipManager.createRelationshipQuery(GroupMembership.class);
      query.setParameter(GroupMembership.GROUP, group);
      query.setParameter(GroupMembership.MEMBER, user);
      // user is assigned with two groups
      List<GroupMembership> resultList = query.getResultList();
      return resultList.size() > 0;
    }
    return false;
  }
}

但是 SPAuthorizer 的 hasGroup 中的 Identity 实例与我在 AuthorizationChecker 中的实例不对应。我在调试器中检查了它。当我执行 identity.getAccount(); 时,尽管用户已通过身份验证,但它返回 null。知道该怎么做吗?

最佳答案

问题出在 Controller 中缺少注释@Stateless。

有可行的例子 https://github.com/lynx-r/picketlink-deltaspike-authorization-and-idm-custom-identity-model .

关于java - 自定义 IDM 身份验证和授权者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24860038/

相关文章:

azure - 使用 Azure AD 进行 React-Native 身份验证

ruby-on-rails - rails : put and interruption in before filter

java - 在 Tomcat 中部署 Web 应用程序

java - 为什么rabbitmq队列绑定(bind)会自动更改?

typescript - 使用数据库的环回 4 身份验证

jboss - JBoss EAP 7.0 上的 SAML 服务提供商

java - Picketlink:查找具有给定角色的用户

java - 在JFrame中显示移动 block

java - 为什么我得到 "Unable to start service Intent"?