ClassCastException implies that the class was loaded by different classloader.
and you are trying to cast a class loaded by different classloader..How did you package and deploy the class ?
I packaged my custom Principal, lets call it, "MyCustomPrincipal" and MyCustomLoginModule within the WAR file containing my web application. I figured as long as it's in the class path it should be fine.
Within the MyCustomLoginModule when I call request.getPrincipal after authentication and cast it to MyCustomPrincipal. I get the classcast because some kind of way It is returning a JBoss simple principal. Even though I configured my login module to have a MyCustomPrincipal.
Try this :- (1) JAR the following classes MyCustomPrincipal and MyCustomLoginModule .
(2) Put the JAR in $HOME/server/default/lib.
(3) Modify the run.sh or run.bat to pick up this JAR in its classpath.
(4) Remove these classes from your WAR.
This way, the module and its customPrincipal are in the server's CLASSLOADER and not in the WAR's CLASSLOADER. Remember, the JAAS module is used for securing all applications that run on the Server & not individual web application
(5) Now the casting should work.
Moving my LoginModule to a seperate JAR still does not work. I have one correction. The classcastexception does not occur in the CustomLoginModule. It occurs in a servlet(spring controller) that has access to the httprequest object.
The following calls: request.getUserPrincipal().getClass() returns an object of type: org.jboss.security.SimplePrincipal
Where as I am expecting my custom class. I have updated login-config as follows:
<application-policy name = "xxx-Domain">
flag = "required">
I am also using JBoss' WebAuthentication class to have JAAS authentication work with programmatic security.
The classcastexception does not occur in the CustomLoginModule. It occurs in a servlet(spring controller) that has access to the httprequest object.
This means that the CustomPrincipal is located in 2 places. May be in your WEB-INF/lib or WEB-INF/classes. Get rid of that. The jar containing your login module and CustomPrincipal should be in the server classpath, visible to Server Classloader. This indicates your class is being picked up by 2 classloaders
Also why do you have your login-config.xml have 2 entires as below ? Shouldn't there be one entry ? Please also check your login Module to make sure you are instantiating your CustomPrincipal as opposed to Jboss SimplePrincipal
<module-option name="principalClassName"> xxx.xxx.CustomPrincipal </module-option> <module-option name="principalClass"> xxx.xxx.CustomPrincipal
The extra module option was just experimination. A forum that I went to had principalClassName instead of principalClass.
I was able to figure out my problem using the following URL:
Group customGroup = new SimpleGroup("CallerPrincipal");
customGroup.addMember(getIdentity()); where get Identity returns the principal that i want to be at request.getUserPrincipal().
The URL read:
"You can also include a custom principal by using code from a login module. A custom principal must be installed under the Subject using a java.security.acl.group named "CallerPrincipal" with the sole group member being the custom "
I oringinally took "also" to mean not required and that I can use just the module-option. But that didnt work.