Injecting of DAO instance into Arquillian test is not aware of Picketlink authorization process
smikloso Nov 5, 2013 8:17 AMHi,
I have very basic setup:
1) REST endpoint NOT annotated with @Secure from aerogear-security
2) service in that REST endpoint method which does some operation on database, methods of that service are NOT annotated with @Secure from aerogear-security
3) methods in DAO class which are called in that service methods (DAO is injected into service), some methods of that DAO class ARE annotated with @Secure annotation.
I know that I can not expect that all Arquillian guys know how that @Security annotation works but, very briefly, from the implementation point of view, it is just simple interceptor https://github.com/aerogear/aerogear-security/blob/master/src/main/java/org/jboss/aerogear/security/interceptor/SecurityInterceptor.java which intercepts these calls and it just checks it I am logged in and if I am, I can proceed, otherwise exception is thrown.
When I am testing this setup manually, all works ok. When I login as admin in one rest call, after that, I can call that REST endpoint in another rest call, which in turn calls service layer which in turn calls DAO layer annotated with @Secure. I do this with CURL and I get what I expect.
However, when I am doing it like this:
https://gist.github.com/smiklosovic/fe5838598a524afdb775#file-gistfile1-java-L81
it seems to me that when I do login in the first method, I should be in the same position as with the command line login, I should be authorized to do that operation in 2nd method, (200 is returned, cookies are returned, all is good, I am logged in) but I am not from LinkDao point of view. When that 2nd test runs, it fails and it ends up with AeroGearSecurityException - not authorized.
It is interesting that it works "in one run" meaning I do that from REST point of view but when I inject LinkDao into test, I should have the very same container reference of it as in case I am doing it rest-like on the command line so it should be the same - and that is apparently not the case.
How is picketlink related to aerogear-security regarding of sessions is big unknown. What kind of reference do I get after injecting it into test? Why is not that DAO class aware of my authorization? It seems that when I inject it into test, that DAO is not aware of previous steps regarding of the authorization.
I guess that problem will be that even I do get that DAO reference, it is unaware of that REST session / request scope so it fails afterwards since it arrived into the test from nowhere, it does not have any idea that I am already logged in previously, it is just taken from who-knows-where.
How do I get the "right" reference to that DAO class which is aware of the logging so it knows that I am ok to do some operation?
That DAO looks like
public class LinkDaoImpl implements LinkDao { @Override @Secure({ "admin" }) // when I am logged with a user which is in "admin" role, I can proceed, otherwise AeroGearSecurityException is thrown public Long countForUser(String userId) { return (Long) createNamedQuery("Link.countForUser", Long.class).setParameter("userId", userId).getSingleResult(); } }
I am deploying whole application as a WAR file, from the deployment point of view, I do these tests on the application which is the very same one as when I try that in manual way, via jboss-as:deploy and doing some curl calls afterwards.
Thank you for any hints