• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 989
  • Last Modified:

tomcat 4.0.1 j_security_check error (jdbc realm)

hi all,

i am trying to use jdbc realm and when i run the example after making the necessary changes to server.xml and web.xml

i am getting error 500. it is trying to find j_security_check.

the question is what is j_security_check and where is it?

memory realm is working fine.

error 500: http://localhost:8080/examples/jsp/security/protected/j_security_check
0
ahuen
Asked:
ahuen
  • 11
  • 10
  • +1
1 Solution
 
cheekycjCommented:
j_security_check AFAIK is a j2ee defined pointer.

It doesn't really exist. Your servlet container should know when it sees it.

If you access tomcat's port directly (8080) then it should work fine.

This might be a case of Apache not knowing to direct to Tomcat when it encounters that URL.

To get details on j_security_check read section 12.5.3 and the login note 12.5.3.1 in the Servlet 2.3
spec, which you can get from here:
http://www.jcp.org/aboutJava/communityprocess/final/jsr053/

a quick blurb from it:


Formbased login and URLbased session tracking can be problematic to implement.
Form based login should be used only when sessions are being maintained by
cookies or by SSL session information.
In order for the authentication to proceed appropriately, the action of the login
form must always be j_security_check. This restriction is made so that the login
form will work no matter which resource it is for, and to avoid requiring the server
to specify the action field of the outbound form.
Here is an example showing how the form should be coded into the HTML
page:
<form method=”POST” action=”j_security_check”>
<input type=”text” name=”j_username”>
<input type=”password” name=”j_password”>
</form>

HTH,
CJ
0
 
grittoCommented:
You don't have to pass to the j_security_check as an action phase.
Only the login page has to use that action in order to validate your username and password.
Use for example the home page inside the restricted area:
 http://localhost:8080/examples/jsp/security/protected/home.jsp and leave the login.jsp with the example above in another unrestriced area (like /login).
When a user start to navigate will be redirected automatically to the login page(because your home page is protected and you are not authenticated), perform the security check and go to the desired page if the username and pwd are ok.
0
 
ahuenAuthor Commented:
i think my problem is that i broke something when i sub class JDBCRealm and override the authenticate method.

anybody have any experience with sub classing JDBCRealm?

If i use JDBCRealm it works.

thanks.
al
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
cheekycjCommented:
0
 
ahuenAuthor Commented:
CJ,

thanks in advance.
here's the method:

 //override to use UserProfile
  public synchronized Principal authenticate(Connection dbConnection,
                                               String username,
                                               String credentials)
        throws SQLException{

        UserLogin.UserProfile userProfile = null;
        ArrayList list = new ArrayList();

        try {
                dbConnection = DatabaseDescriptor.User.getConnection();
                userProfile=UserLogin.login(dbConnection, username, credentials);
                if (userProfile == null) {
                    return (null);
                }

                // Validate the user's credentials
                boolean validated = false;
                if (userProfile.isDCAvailable()) validated=true;

                if (validated) {
                    if (debug >= 2)
                        log(sm.getString("jdbcRealm.authenticateSuccess",
                                         username));
                } else {
                    if (debug >= 2)
                        log(sm.getString("jdbcRealm.authenticateFailure",
                                         username));

                    return (null);
                }

                // Todo: read from db
                list.add("Slave");
                dbConnection.commit();

        } catch (Exception e) {
                log(e.getMessage());
                return null;
        }
        // Create and return a suitable Principal for this user
        return (new NetRiskPrincipal(this, username, credentials, list));

    }
0
 
cheekycjCommented:
one more question.. if you put logging throughout the method.. is it being called... can you follow the flow??

CJ
0
 
ahuenAuthor Commented:
CJ,

nothing gets logged.
0
 
cheekycjCommented:
even if you add:

log("In my authenticate method");
as the first line of the method??

CJ
0
 
ahuenAuthor Commented:
how do i do that? or rather where?

i was logging in the method...
System.out.println(....)

thanks.
0
 
cheekycjCommented:
read this:
http://tomcat.mslinn.com/tomcat/realms.html

the last two sections are about overriding authentication in jdbc realms in 3.2.x and 4.x

CJ
0
 
ahuenAuthor Commented:
CJ,
I thought you have to subclass JDBCRealm and override it's methods because in server.xml JDBCRealm is set by

 <Realm  className="org.apache.catalina.realm.JDBCRealm" debug="99"
             driverName="sun.jdbc.odbc.JdbcOdbcDriver"
          connectionURL="jdbc:odbc:xyz" connectionName="abc" connectionPassword="abc"
           userTable="tmp" userNameCol="user_name" userCredCol="user_pass" />

so if you subclass JDBCRealm you can set it the realm class to className="com.xyz.stuff.MyRealm"
0
 
cheekycjCommented:
It looks as though that was the case in Tomcat 3.x but as of 4.x you just subclass the authenticator class.

CJ
0
 
ahuenAuthor Commented:
if i only subclass and override org.apache.catalina.authenticator.FormAuthenticator.authenticate, and authenticate calls

Realm realm = context.getRealm();
principal=realm.authenticate(username, password);

this means that it is still using JDBCRealm.authenticate(...) which expects the user table, etc and that implies that I would not be able to use my UserProfile.

hmmmm
0
 
ahuenAuthor Commented:
oops...
i see ...
i forgot the part where i am overriding.. it is up to me what to do in the code....

but still the part where

Realm realm = context.getRealm();
principal=realm.authenticate(username, password);

should still work. right?
0
 
ahuenAuthor Commented:
hmmm...
but if i override org.apache.catalina.authenticator.FormAuthenticator

and my new class is in my package how would tomcat know to use my class instead of the base class?
0
 
cheekycjCommented:
isn't that in the login-config in the web.xml?

CJ
0
 
ahuenAuthor Commented:
CJ,

Found the problem...
it wasn't finding one of my jars...

I have another question...

how do you set up so that tomcat won't require a user to have a role to log in? if i omit the <auth-constraint> it won't show the login. teh role "slave" is being added to the Principal but it is not finding it.

at this point i don't need the role functionality.

thanks.

    <security-constraint>
     
     <web-resource-collection>
         <web-resource-name>User Protected Area</web-resource-name>
          <url-pattern>/ovdc/*</url-pattern>
            <http-method>DELETE</http-method>
          <http-method>GET</http-method>
            <http-method>POST</http-method>
           <http-method>PUT</http-method>
      </web-resource-collection>

      <auth-constraint>
       <role-name>slave</role-name>
      </auth-constraint>

    </security-constraint>
0
 
cheekycjCommented:
can you override the hasRole() method to always return true?

CJ
0
 
ahuenAuthor Commented:
CJ,

where is hasRole() located?

thanks.
0
 
cheekycjCommented:
should be in JDBCRealm.

CJ
0
 
cheekycjCommented:
actually hasRole() is in RealmBase which JDBCRealm extends (so it inherits both the authenticate and hasRole methods from it)

CJ
0
 
cheekycjCommented:
Thanx for the "A".

CJ
0
 
TomBruserCommented:
Simple solution:

At the start of your login and login-error pages, include the following:

    if (request.getAttribute("javax.servlet.forward.request_uri") == null) {
        response.sendRedirect("/index.jsp");
    }

where /index.jsp is equivalant to some acceptable page to forward users to if they have inadvertantly hit the back button to reach the login page.

To create a logout function, make a logout.jsp that contains the following:

        session.invalidate();
        response.sendRedirect("/index.jsp");

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 11
  • 10
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now