Apache authentication with JBoss authorisation
tim.penhey Oct 17, 2002 12:42 PMHere is the situation.
The company that I work for has an apache instance (somewhere, maybe more than one) that handles authentication. I want to be able to have secure webapps and EJBs that have role based authorisation.
Firstly:
Solaris
Sun JDK 1.4.0
JBoss 3.0.3, w/ Tomcat 4.0.4
I have managed to get this working, but have one question.
Here is how it works:
A Ajp13Connector is defined in the tomcat4-service.xml file. The war file that I create has a jboss-web.xml file in the WEB-INF directory with a <security-domain> tag to point to the right policy in the login-config.xml. The web.xml for the war defines a basic auth-method.
The first problem was the catalina definition of authenticated. Basically if there is a principal for the request context then the user is authenticated. The Ajp13Connector creates an Ajp13Principal with the username that apache has authenticated. Now when the tomcat container then asked the Realm if the authenticated user had a particular role, the Realm (JBossSecurityMgrRealm) then said that the user was not authenticated.
After a week of reading catalina and jboss source code, this is what I have come up with.
Unfortunately the JaasSecurityManager that comes with JBoss is not friendly to classes that want to derive from it, so I had to make a copy of the source code, change the name and stick it in another package. Basically all I wanted to do was to add a bit in the doesUserHaveRole method that will try to log in the principal if the Subject is null. In order for this to work, I also created another LoginModule.
The login module that I wanted in general was the DatabaseServerLoginModule so we could store our usernames and roles in a database. So I created another class that derived from that one, and called it ApacheDatabaseServerLoginModule. In the initialize method, a copy of the principal is stored in a private variable using the SecurityAssociationCallback to get the principal. When the login method is called, a check is made to see if the principal is implemented using org.apache.ajp.tomcat4.Ajp13Principal, and if it is the function returns true, and if not, it calls the derived login.
Effectively what happens is the following steps:
1) Incomming connection from apache with a set principal
2) Tomcat believes that the user is already authenticated.
3) Asks the security manager to see if the principal has said role
4) Security manager has no set subject, and checks to see if principal is an Ajp13Principal. If it is, it calls isValid to initiate login.
5) Login method on derived apache login module is called, and the principal is an Ajp13 one so success.
6) ApacheSecurityManager updates the cache with the DomainInfo and sets the active subject on the SecurityAssociation.
7) Roles are now checked properly.
Now, my question is...
The next time a request is made by the user, the active subject on the SecurityAssociation is not set, so it goes through the isValid function again. This time it is caught by the validateCache method, and goes on from there. Why is the active subject not set?
Also as a not the the author of the JaasSecurityManager, can we have the private methods as protected please? This would have meant that I could have just derived from the class instead of replaced it.
Tim