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.