Jump to content
Changes to the Jaspersoft community edition download ×

Problem with external authentication and hibernate


bbergquist

Recommended Posts

I've got JasperServer 2.1.0 working with Glassfish V2 and Apache Derby. I connected JasperServer authentication to my own JDBC authentication realm in Glassfish. I ran into an issue however when the my external users and roles are migrated over to the JasperServer security domain. This occurs when both a new user and a new role are being migrated over from the external security realm.

 

Hibernate was throwing an exception stating that a relationship to an unknown object was found when persisting. I traced this down and found that when a new external role is migrated over to JasperServer, it creates and persists role but later when the new user is persisted, the code goes through and finds the roles and associates the roles with the user. But with a brand new role that was just added, Hibernate does not find the role when executing the query.

 

I fixed this problem by adding getHibernateTemplate().flush() to "putRole" in UserAuthorityServiceImpl.java:

 

Code:

/* (non-Javadoc)
* @see com.jaspersoft.jasperserver.api.metadata.user.service.UserAuthorityService#putRole(com.jaspersoft.jasperserver.api.common.domain.ExecutionContext, com.jaspersoft.jasperserver.api.metadata.user.domain.Role)
*/
public void putRole(ExecutionContext context, Role aRole) {
RepoRole existingRole = getRepoRole(context, aRole.getRoleName());
log.debug("putRole: " + aRole.getRoleName() + ", " + existingRole);
if (existingRole == null) {
existingRole = (RepoRole) getPersistentClassFactory().newObject(Role.class);
log.debug("New Object"«»);
}
existingRole.copyFromClient(aRole, this);
getHibernateTemplate().saveOrUpdate(existingRole);
// XXX
getHibernateTemplate().flush();
// XXX

Set repoUsers = existingRole.getUsers();
for (Iterator it = repoUsers.iterator(); it.hasNext();«») {
RepoUser repoUser = (RepoUser) it.next();
repoUser.getRoles().remove(getPersistentObject(aRole));
}

Set users = aRole.getUsers();
for (Iterator it = users.iterator(); it.hasNext();«») {
User user = (User) it.next();
addRole(context, user, aRole);
}

}

 

This causes the newly created Role to be found when the query in getRepoRole is executed.

 

Should this be logged as a bug with a possible fix?

Link to comment
Share on other sites

  • Replies 10
  • Created
  • Last Reply

Top Posters In This Topic

  • 2 weeks later...

Lucian, I was just about to go enter a bug for this. I had to create an account and got sidetrack but finally got around to it today. I saw this bug

 

http://jasperforge.org/sf/go/artf3008?nav=1

 

 

This seems to be the same bug. I don't know how (or if I can) update the bug with my comments so I'm posting here instead but I think the fix that I provided will take care of this problem. It did for me.

 

Brett

Link to comment
Share on other sites

I was planning to investigate whether your case is the same as the one described in artf3008. Are you getting the same exception? The description seems similar to your scenario..

 

The current trackers only permit comments from the original bug reporter and project admins; this is something we are planning to fix. In the meantime, please post your comments on the issue on this thread (the bug includes a link to this discussion).

 

Regards,

Lucian

Link to comment
Share on other sites

The scenario in the bug report is exactly the same scenario that I had with the exception that the bug reporter was using LDAP as the external authentication source and I'm using an external JDBC source.

 

The symptom of the user being created and the roles being created but the roles not be associated with the user, the exception being thrown, and the fact that subsequent login with that user corrected the roles to group association is exactly the same.

 

What is happening is when the user to role association is being done down in the code, the a query is performed to lookup the role. But in this case the role is newly created (probably within the same transaction) and the query does not see the role. Some persistence providers would flush any objects from memory to the persistence storage before performing the query but I don't believe that is required by spec. So the query does not find the role created and the one that it associated with the user object is just an in memory role with no persistence. When the user is persisted, the exception occurs because you now have a persistence managed user associated with non-persistence managed role.

 

Putting the flush in when the role is created ensures that later when the query for the role is done, it will find the role and return a persistence managed role. Now when the role is associated with the user and the user is persisted, both are persistence managed and no error occurs.

 

Since at any point it is allowed to perform a flush, there really is no risk in putting in the change I mentioned. The only downside might be a performance hit if you were performing this operation many times very frequently because you are now causing the persistence cached object to be synchronized with storage (ie. a database update or insert) where it might be more efficient to batch this up later. In this use case, however, it is very unlikely that roles are created very frequently and repeatedly so the flush will occur at most once per role being created.

Link to comment
Share on other sites

We'll investigate this bug as soon as possible. I know that flushing the session is generally harmless, but we still need to replicate the issue before checking-in a fix.

 

This seems not to happen on MySQL, maybe because the MySQL identity generator requires objects to be written to DB as soon as Session.save is called. We'll test this on Oracle or Derby.

 

Regards,

Lucian

Link to comment
Share on other sites

Lucien, I would certainly be able to give this a try but I'm having trouble (not familiar) with how to find what the fix actually was. Would it be possible to send me the changed file or give me just a little more info an what I need to do to my local build to put in the same fix.
Link to comment
Share on other sites

You can test the fix by copying the attached applicationContext.xml into the JasperServer WEB-INF folder. The fix consists the following (highlighted) line:

Code:

<bean id="userAuthorityService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="userAuthorityServiceTarget"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="put*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="addRole*">PROPAGATION_REQUIRED</prop>
<prop key="enableUser*">PROPAGATION_REQUIRED</prop>
<prop key="disableUser*">PROPAGATION_REQUIRED</prop>
<prop key="maintainInternalUser">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS</prop>
</props>
</property>
</bean>

 

Regards,

Lucian [file name=applicationContext-1ae2f344fdb57e27fe602e6562c6f3da.xml size=38466]http://www.jasperforge.org/components/com_joomlaboard/uploaded/files/applicationContext-1ae2f344fdb57e27fe602e6562c6f3da.xml[/file]

Link to comment
Share on other sites

  • 2 months later...
  • 1 year later...

Hmmm, the fix works for us on JasperServer 3.0 and PostgreSQL but causes org.hibernate.exception.ConstraintViolationException when the same user executes reports concurrently.

 

Removing <prop key="maintainInternalUser">PROPAGATION_REQUIRED</prop> when users have already been synced allows concurrent execution.

 

Will try upgrading to 3.5 to see if it is resolved.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...