IDM not persisting. Custom Authenticator and model.
vwjugow May 23, 2014 2:32 PMHi,
I am trying to get picketlink working in my application. It uses Errai, so I'm using the picketlink jar provided by Errai Security.
I've implemented a custom Authenticator, and it authenticates ok, and when I do identity.getAccount() it returns me the logged in user.
But I would like to use Roles as well, and I figured that for that I need the IDM (correct me if I'm wrong in anything please, I don't quite understand how best to implement picketlink and what exactly needs to be done.)
I'm not using Picketlink default Entities like User, because I wanted to maintain my model. So I've extended some of the entities with custom ones.
For instance:
package com.magick.models.shared;
public class UserImpl extends org.picketlink.idm.model.basic.User {
private com.magick.models.shared.User user; //My model User
public UserImpl() {}
public UserImpl(com.magick.models.shared.User user){
this.user = user;
setEnabled(true); // True! as we don't have the notion of enabled account right now
setLastName(user.getLastName());
setFirstName(user.getFirstName());
setEmail(user.getId());//hack to have the id.
setId(user.getId());//we can't retrieve this later..
setLoginName(user.getUsername());
}
public com.magick.models.shared.User getUser(){
return user;
}
}
I've done the same as above for Role class.
Then I've copied all these classes from Picketlink to my project:
AbstractCredentialTypeEntity, AccountTypeEntity, AttributedTypeEntity, AttributeTypeEntity, DigestCredentialTypeEntity, GroupTypeEntity, IdentityTypeEntity, OTPCredentialTypeEntity, PartitionTypeEntity, PasswordCredentialTypeEntity, RelationshipIdentityTypeEntity, RelationshipTypeEntity, RoleTypeEntity, X509CredentialTypeEntity
And added them to my persistence.xml like this:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="pu-magick" transaction-type="RESOURCE_LOCAL"> <!-- TODO: JTA --> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/datasources/magick</jta-data-source> <class>com.magick.models.shared.User</class> ... <class>com.magick.models.shared.Symbol</class> <class>com.magick.models.security.AttributedTypeEntity</class> <class>com.magick.models.security.AccountTypeEntity</class> <class>com.magick.models.security.RoleTypeEntity</class> <class>com.magick.models.security.GroupTypeEntity</class> <class>com.magick.models.security.IdentityTypeEntity</class> <class>com.magick.models.security.RelationshipTypeEntity</class> <class>com.magick.models.security.RelationshipIdentityTypeEntity</class> <class>com.magick.models.security.PartitionTypeEntity</class> <class>com.magick.models.security.PasswordCredentialTypeEntity</class> <class>com.magick.models.security.AttributeTypeEntity</class>
Then I have this class:
public class PicketlinkResources {
@Produces
@PicketLink
@PersistenceContext(unitName = "pu-magick")
private EntityManager em;
}
And finally, my custom authenticator:
@PicketLink
public class MagickAuthenticator extends BaseAuthenticator {
@Inject
DefaultLoginCredentials loginCredentials;
@Inject
private PartitionManager partitionManager;
@Inject
private UserDAO userDAO;
@Override
public void authenticate() {
String userId = loginCredentials.getUserId();
String password = loginCredentials.getPassword();
User user = userDAO.fetchUserByName(userId);
if (!BCrypt.checkpw(password, user.getPasswordHash())) {
setStatus(AuthenticationStatus.FAILURE);
} else {
UserImpl account = new UserImpl(user);
setStatus(AuthenticationStatus.SUCCESS);
setAccount(account); //sets the account to identity
//HERE I TRY TO ADD USER TO IDM
final IdentityManager identityManager = partitionManager.createIdentityManager();
IdentityQuery<UserImpl> query = identityManager.createIdentityQuery(UserImpl.class);
query.setParameter(UserImpl.LOGIN_NAME, user.
List<UserImpl> result = query.getResultList();
org.picketlink.idm.model.basic.Role trial = new org.picketlink.idm.model.basic.Role("TRIAL");
if (result.isEmpty()){
identityManager.add(account); //SHOULDN't THIS PERSIST SOMETHING TO DB ?
identityManager.updateCredential(account, new Password(password));
//final RelationshipManager relationshipManager = partitionManager.createRelationshipManager();
}
//Since I've added the user to IDM, let's try if it would authenticate using IDM and not cheking password manually
Credentials creds = new UsernamePasswordCredentials(user.getUsername(), new Password(password));
identityManager.validateCredentials(creds);
if (Credentials.Status.VALID.equals(creds.getStatus())) {
logger.info("YUUUUUUUUUUUUUWHOOOOOOOOOOOOOOOOOOOOOOO");//NEVER GETS CALLED
}
}
So after running that code, nothing get's persisted to my database, though the tables were created automatically.
One last detail, the persistence.xml, authenticator, PicketlinkResources reside in my UI project, and all the Entities in a separate jar.
I'm pretty sure I'm doing several things wrong, could you point me in the right direction ? I tried reading documentation, but I get a little lost.