Reputation: 4402
we have a simple web application running on Tomcat 7.0.56. Now we want to use our own realm for authentication.
public class SpecialAuth extends DataSourceRealm{
@Override
public Principal authenticate(String username, String credentials){
....
}
}
This is defined in the /META-INF/context.xml inside the war
<Context>
<Realm className="some.package.SpecialAuth" dataSourceName="jdbc/MySQL" />
</Context>
Where to put the SpecialAuth.class?
What we expected was simply to have the SpecialAuth.class inside our war but then we're getting folling exception on startup
Caused by: java.lang.ClassNotFoundException: some.package.BackOfficeAuth
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
....
If we make a jar, putting it into $TOMCAT/lib everything works fine.
But this CAN'T be the solution! That would mean every time I work on this class(es) I have to touch my tomcat server and can't use the normal deployment.
How can I use the build-in authentication mechanism without touching the tomcat all the timeß
Upvotes: 0
Views: 425
Reputation: 4402
As you said I don't like your answers :) So what I did (and I'm 100% sure that you don't like it) was to set the realm on the dirties possible way BUT now I can run it on a ontouched tomcat. After 163 acceptance tests nothing seems to break.
public final class ContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
ServletContext servletContext = event.getServletContext();
TomcatContextManipulator tomcat = new TomcatContextManipulator(servletContext);
tomcat.applyRealm(new MyOwnRealm());
}
}
.
public class TomcatContextManipulator {
private static final String EXPEXCTED_TOMCAT_VERSION = "7.0.52.0";
private ApplicationContextFacade servletContext;
/**
* @param servletContext must be of type {@link ApplicationContextFacade}
*/
public TomcatContextManipulator(ServletContext servletContext) {
checkTomcatVersion();
ensureEquals(servletContext.getClass(), ApplicationContextFacade.class, "class of servletContext");
this.servletContext = (ApplicationContextFacade) servletContext;
}
/**
* checks if the correct version of tomcat is in use, throws {@link IllegalStateException} if not
*/
private void checkTomcatVersion() {
// we use several internal parts of tomcat (for example with reflection)
// by doing this we bind ourself hardly to a explicit version
ensureEquals(EXPEXCTED_TOMCAT_VERSION, ServerInfo.getServerNumber(), "Tomcat-Server-Version");
}
/**
* overrides the existing realm with the given on
*/
public void applyRealm(Realm realm) {
ensureNotNull(realm, "realm");
ApplicationContext applicationContext = (ApplicationContext) ReflectionUtil.get(servletContext, "context");
StandardContext standardContext = (StandardContext) ReflectionUtil.get(applicationContext, "context");
standardContext.setRealm(realm);
}
}
Note:
Upvotes: 1