Hi all,
I have been trying to use a custom JAASRealm loginmodule in my code and running into exception or 403 access denied error message. I have searched for an answer in the Tomcat FAQ, on the net using general google search, searched the bugs list. But did not get an exact answer to the problem I am facing.
Here is the details of the configuration and code I have setup on a tomcat 6.0.18 running on a Windows machine.
Tomcat 6.0.18 is running on a windows box. The following realm configuration is inside the 'Engine' element of the server.xml:
<Realm className="org.apache.catalina.realm.JAASRealm"
appName="securitytest"
userClassNames="com.genuvation.commons.security.User"
roleClassNames="com.genuvation.commons.security.Role" debug="99" />
Here is my jaas.config which is in the %CATALINA_HOME%/conf directory:
securitytest {
com.genuvation.commons.security.MyLoginModule required debug=true;
};
This jaas.config file is specified in the %CATALINA_HOME%/bin/catalina.bat file as part of JAVA_OPT:
set JAVA_OPTS=%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%\conf\jaas.config
Here is the source code for a custom loginmodule. This code is part of a common.jar class which has been compiled and placed as in the %CATALINA_HOME%/lib
public class MyLoginModule implements LoginModule {
private Subject subject;
private CallbackHandler callbackHandler;
private String password;
private String name;
public boolean abort() throws LoginException {
return true;
}
public boolean commit() throws LoginException {
subject.getPrincipals().add(new User(name));
subject.getPrincipals().add(new Role("role1"));
System.out.println("The commit method succeeded in the loginmodule returning true");
}
return true;
}
private boolean isBlank(String value){
boolean bRet = true;
if(null!=value){
bRet = (value.trim()).isEmpty();
}
return bRet;
}
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
}
public boolean login() throws LoginException {
NameCallback name = new NameCallback("User name");
PasswordCallback password = new PasswordCallback("Password", false);
try {
this.callbackHandler.handle(new Callback[] { name, password });
this.name = name.getName();
System.out.println("The name is" + this.name);
if(password.getPassword()!=null)
this.password = new String(password.getPassword());
if (isBlank(this.name)) {
throw new CredentialNotFoundException("User name is required");
}
if (isBlank(this.password)) {
throw new CredentialNotFoundException("Password is required");
}
return true ;
} catch (Exception e) {
throw new LoginException(e.getMessage());
}
System.out.println("The login method succeeded in the loginmodule returning true");
return true;
}
public boolean logout() throws LoginException {
return true;
}
}
The following is the web.xm file security section:
<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>role1</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>authenticator-realm</realm-name>
</login-config>
<security-role>
<role-name>role1</role-name>
</security-role>
When I run the tomcat instance with my web-app tbiservices.war file in the %CATALINA_HOME%/webapp directory and all the configuration in place and I hit the URL for the servlet, I get a browser dialog box popped up for Username and password as expected. When I put in any user-id, password in the box and hit ok, the page redirects to a "403 Access Denied" page without any message in the log. I can see that the loginmodule was hit, as the few system.out.println messages show up in the log. I tried, moving the JAASRealm to the web-app meta-inf/context.xml and setting contextclassloader = true in the realm did not work. moving the loginmodule containing common jar down to the webapp web-inf generates and exception that the loginmodule was not found. My question is, how can I make it work? Or is there a bug? It should just pop-up the dialog box and for any pair of user-password succeed and direct us to the resource. Please advise, or point to any appropriate bug/document etc. I can not make any progress without some more pointers.
Thanks.
-Andy Basu