aspose file tools*
The moose likes Tomcat and the fly likes Tomcat 7 custom authenticator valve not being triggered Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Products » Tomcat
Bookmark "Tomcat 7 custom authenticator valve not being triggered" Watch "Tomcat 7 custom authenticator valve not being triggered" New topic
Author

Tomcat 7 custom authenticator valve not being triggered

Eric Ases
Greenhorn

Joined: Nov 17, 2010
Posts: 4

I have made a custom authenticator to use with tomcat's container-managed security which provides some extra features on top of the basic FormAuthenticator (including some cookie handling, etc). In previous versions of Tomcat (6.0.29) I was able to declare this in the <Context> in server.xml and it would be triggered when a request was made before trying to perform the database lookup. I have recently upgraded to Tomcat 7.0.19, but this Valve seems to always get bypassed. I have searched and could not find an explanation of anything changing with this.

The entry for this app in my server.xml is:


where MyCustomAuthenticator is my custom authenticator which extends FormAuthenticator. My web.xml is configured such that the form authentication does happen correctly, but the issue is the Valve isn't used first.

Am I doing something wrong here, or is there a new way to handle this in Tomcat 7?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16236
    
  21

I don't even know how you managed to get it working in Tomcat 6!

If you created a custom A&A Realm, it should have been referenced in the Realm element of your Context, not as a Valve.

Valves are basically monitors and modifiers of the network traffic in and out of webapps. The JEE container security system could be considered as a Valve, but it's already tightly integrated into the process. The Realm is just the plugin part that handles the actual vetting of credentials and of roles.

Assuming your Realm is using a database as a reference for security, the proper definition should look more like this:


You can then present the properties "dataSourceName", "localDataSource", etc. on your Realm class definition or you can subclass the DataSourceRealm to create your Realm and let the properties be inherited. I did this recently to create a Realm that allowed case-insensitive userIDs, since (oddly), the standard database Realm din't support that.


Customer surveys are for companies who didn't pay proper attention to begin with.
Eric Ases
Greenhorn

Joined: Nov 17, 2010
Posts: 4

Thanks, Tim. Apparently I was unknowingly taking advantage of some undocumented behavior in Tomcat 6.

I have a follow-up question now... is there any way to access the Request object from the custom Realm? Basically, what I am trying to do is check if the user has a cookie set from a previous session, then do special processing (and "remember me" logic) before attempting the normal container authentication. I've tried using a filter or listener in my webapp, but Tomcat's authentication steps in before the request gets that far. Is there any hook before Tomcat's authentication happens?

Perhaps I'm not searching for the right thing, but I haven't been able to find any information on implementing "remember me" cookies in conjunction with Tomcat's form authentication. Is it just not possible without re-implementing the authentication mechanism yourself? This has to be a common issue, so I'm not sure what I'm missing.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16236
    
  21

The Realm Interface actually knows nothing about HTTP at all. All it knows is "validate userid/password" and "does user possess security role?". It doesn't and cannot assume that the user had cookies enabled - they may be using rewritten URLs, instead.

The application can read/write cookies, although you should never keep security-critical information in cookies (cookies can be hacked - store handles to security objects in cookies, instead).

The actual login process, isn't visible to the application. The closest you can get is to observe the HttpServletRequest object and mark the transition from a null userid to a non-null userid. In some systems, such as single-signon security systems, the user may have done their actual login elsewhere.

If you want to keep a userid in a cookie, you MIGHT be able to access it locally via JavaScript on the login form and pre-populate the login userid control at onload time (I'd have to RTFM). An alternative if only the server can read the cookie would be to put a URL on the login screen to an UNSECURED function to return the value that's in that cookie, and I'm guessing that AJAX might be required, too. Keeping passwords in cookies I definitely don't recommend. Even keeping the userid cuts the time a hacker needs to break in, since 50% of the work is already done.
Amit Singhall
Greenhorn

Joined: Oct 18, 2005
Posts: 4
Hi,

I am facing the similar issue , Custom Form Authenticator is not getting executed with tomcat 7.
I am using the embeded tomcat in my java application.

I am setting the custom realm on engine level
engine.setRealm(realm);
Then I am adding the my custome form authenticator on the context level
StandardContext root = (StandardContext) tomcat.addWebapp(host,"/myApp","/myApp", catalinaHome + "/webapps/myApp");
CustomFormAuthenticator formAuth = new CustomFormAuthenticator ();
formAuth.setDisableProxyCaching( false );
root.addValve(formAuth);

The CustomFormAuthenticator was running in tomcat 5 , but when I upgraded to tomcat 7 , it stopped executing. I have recompiled all the classes with new tomcat libabries. And also I am using Tomcat class instead of Embedded(deprecated in tomcat 7).
Tomcat is getting started but the CustomFormAuthenticator is not getting executed.

Here is the snippet from web.xml


<security-constraint>
<display-name>Custom Framework Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Custom Framework Authentication Required Area</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Custom Role</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/loginError</form-error-page>
</form-login-config>
</login-config>

<!-- Define the security roles referenced by this web application. -->
<security-role>
<role-name>Custom Role</role-name>
</security-role>
Dmitry Stepanov
Greenhorn

Joined: Jan 15, 2012
Posts: 2
Has anybody found a solution how to make that valve is triggered by Tomcat7.

I have
public class ContainerAuthenticator extends FormAuthenticator {
...
configured in META-INF/context.xml
<Context>
<Valve className="mobi.eyeline.teapay.web.auth.ContainerAuthenticator"
...
and it is triggered with Tomcat 6, but it's not triggered with Tomcat7/TomEE.


OCPJP6 | OCE-JWSD6 | OCE-JWCD6 | OCE-EJBD6 | OCE-JPAD6
Dmitry Stepanov
Greenhorn

Joined: Jan 15, 2012
Posts: 2
See https://issues.apache.org/jira/browse/TOMEE-1340

Difference:
Tomcat 6 FormAuthenticator
public boolean authenticate(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response, org.apache.catalina.deploy.LoginConfig config) throws java.io.IOException
{ /* compiled code */ }

TomEE FormAuthenticator
public boolean authenticate(org.apache.catalina.connector.Request request, javax.servlet.http.HttpServletResponse response, org.apache.catalina.deploy.LoginConfig config) throws java.io.IOException { /* compiled code */ }

org.apache.catalina.connector.Response changed to javax.servlet.http.HttpServletResponse response
 
jQuery in Action, 2nd edition
 
subject: Tomcat 7 custom authenticator valve not being triggered