aspose file tools*
The moose likes Glassfish and the fly likes j_security_check failing to authenticate users in JSF application Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Products » Glassfish
Bookmark "j_security_check failing to authenticate users in JSF application" Watch "j_security_check failing to authenticate users in JSF application" New topic
Author

j_security_check failing to authenticate users in JSF application

Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

I'm trying to develop a user authentication system using JSF, JPA and j_security_check in GlassFish4. I'm able to create and populate the USER and GROUP tables using domain entity classes, with the following schema in mySql:


+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| username | varchar(255) | NO | PRI | | |
| password | varchar(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+


-> ;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| groupname | varchar(20) | NO | PRI | | |
| username | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+

When it comes to logging in I am always directed to the error page even though I'm entering the correct username and password to access the 'admin' folder. This tells me that Login might not even be querying the DB.

One warning which caught my eye when trying to log in is:


Not sure if this suggests that j_security_check is already firing a query before I load the Login page or if my configurations are just plain wrong so that the j_security_check isn't even talking to the DB. Any guidance on this and configuring j_security_check in JSF is much appreciated.


The Login.xhtml looks like:



Security constraints on web.xml:



glassfish-resources.xml:



GlassFish 4 realm configuration





Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21

1. You are aware, I hope, that when using the J2EE container security login that the user does NOT request the login page as an explicit URL. It's presented automatically when a secured URL request is made and has no URL of its own. In other words: "http://www.myserver.com:8080/faces/Login.jsf" will not function as a valid request.

2. Server-presented pages such as the login/loginfail, error pages, and similar constructs often don't work properly in frameworks such as JSF that depend on a dispatcher servlet. Not all versions of all servers will route internal requests through the servlet, and if that isn't done, then the JSF lifecycle won't be applied. In any event, container login code is not part of the application, it's part of the webapp server, which doesn't use JSF. And in the case of Tomcat, JSF isn't integrated into the server anyway.

It's also a security risk to put rich content on a login page. My login pages are generally stark html or vanilla JSPs. They aren't provided with menus that could potentially hijack the authentication process and keep the CSS and javascript to a minimum. I save the friendly stuff for people who've passed authentication.


Customer surveys are for companies who didn't pay proper attention to begin with.
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

1. You are aware, I hope, that when using the J2EE container security login that the user does NOT request the login page as an explicit URL. It's presented automatically when a secured URL request is made and has no URL of its own. In other words: "http://www.myserver.com:8080/faces/Login.jsf" will not function as a valid request.


I'm aware that the j_security_check has almost nothing to do with the JSF framework and I'm getting the login form trying to access the admin folder "http://www.myserver.com:8080/faces/admin/adminindex.xhtml"

My login pages are generally stark html or vanilla JSPs


I replaced my login and error forms with a plain html documents without any jsf tags but it did not solve my problem. I"m still re-directed to the error page even when typing the correct UN and PW for admin user.

This looks like a j_security_check servlet issue where the database is simply not being checked for the user credentials? Could the JPA part of the application (where I create users and look up the list of users for administration purposes) be conflicting with j_security_check? The JPA works fine and I'm able to 'administer' user accounts, creating users, creating groups, listing users, groups, etc.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21

OK. Just had to cover the basics. When there's too much detail in the original question, I tend to take the easy way out and make sure that whoever's asking knows the fundamentals.

There isn't a "j_security_check" servlet as such. j_security_check is an indicator to the server's Realm management code that the authentication manager posted a login/loginfail form and this is the client's response to that form. That's why a "http://www.myserver.com:8080/j_security_check" URL request will fail. It's needed because the user could have simply made some other request that aborts the login, and the only way to tell would be by the incoming data.

Your noted error (INFO) message actually sounds like a violation of the JVM's configured security rules. Meaning that even if you have your server authentication set up perfectly, the JVM may be offended. Are you overriding its standard security policies?

I'm a little bit at a loss here, since GlassFish and I never became very good friends. I can tell you definitively that in the Tomcat server the datasource for application database requests will not conflict with the use of a database-related security Realm. Although I believe that their standard Realm module collection includes a Realm that will allow the Realm and Datasource to use a common definition so that you don't have to enter the URL and credentials twice in the configuration if both the connection pool and realm are sharing the same database.

You might want to present your question to the GlassFish forum. Make up a basic app with a secured URL, login/loginfail page and security definitions, make it fail, then report what you've got to them.

If you can get that much working, the only difference in JSF is that you'd want to use the "redirect" option when navigating to secured Views, since the container security looks at URLs, not underlying resources (xhtml, etc.) and without the "redirect" option, the URLs tend to lag the view resources, thus presenting potential security issues.
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10202
    
166

My guess based on that log message is that the authorization seems to be failing. Perhaps the authentication is passing. Have you checked that the query returns back the correct role(s) and it satisfies the role requirement noted in the web.xml for that resource?

By the way, you might want to enable finer level of logging for some appropriate glassfish packages to see what's going on. I've added this thread to the GlassFish forum too.

[My Blog] [JavaRanch Journal]
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

Have you checked that the query returns back the correct role(s) and it satisfies the role requirement noted in the web.xml for that resource?


Yes I've executed selected queries from within the DB console and I'm getting values back for the roles and users. I've also set up a JSF/ JPA admin application and I'm successfully able to manipulate DB values from there too.

I think your advice about fine logging makes sense and I'll be trying that next . Thank you!
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

Took me a while to configure the GlassFish logging, which obviously gave a very long log when i set the javax.enterprise.system.core=FINEST. Some key parts of that log are:



The last few lines above indicate that the permission is failing before the login form actually appears, which tells me that this could be something wrong with the JDBCRealm config in the glassfish admin console?

Also does the following message suggest that the security check might be looking for a FILEREALM instead of a JDBCREALM?

FINE: Domain that failed(ProtectionDomain (file:/UserAdmin2/UserAdmin2 <no signer certificates>)


Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

I have an update but not a solution. In the GF Admin console Security tab, there is a [Default Realm] setting which was set to 'file-realm'. I set this to 'jdbc-realm', which produced a slightly different error log from my prior post:



I'm thinking that the DB user, password and group tables are being read but something is preventing the authentication OR authorization process from completing. Just to test if the tables are being read I set the tables to a dummy value (jdbcrealm.users, jdbdrealm.groups). I got a 'table does not exist' error in the log, which is no longer there when i simply refer to the tables as 'users' and 'groups'.

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21

The default Realm is simply the Realm used when a webapp didn't have a specific Realm configured for that application.

Here is the abstract form of the JDBC Realm's authenticate method, invoked when you are using the JDBC Realm and a j_security_check submission is being processed by the server:



Actual code will plug in the appropriate table and field names to the SQL, and may construct a UserPrincipal object, but this is the essence. Note that the SQL never actually exposes the database copy of the userID or password, simply verifies that they match. Makes it harder for hackers to retrieve and exploit secret information.

The important thing to note is that this is a boolean function, not something that throws an exception like your stacktrace indicates. I think that there should be further information in your stack trace to indicate why the exception was thrown.

There are 2 messages in your log that bear investigating:

FINE: [Web-Security] Checking Web Permission with Principals : null

While it may simply mean that the user isn't logged in yet (UserPrincipal is still null), it might also be talking about the security under which the actual security check is being conducted.

The second message:

FINE: [Web-Security] hasResource isGranted: false

Is harder to comprehend.
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169


There are 2 messages in your log that bear investigating:

FINE: [Web-Security] Checking Web Permission with Principals : null


I can neither get more information on these errors from the stack trace nor Am I finding much online. I have set the logging to FINEST so isn't this the most granular level of logging?


After trying to configure the connection pool in the GlassFish admin console (using exactly the same parameters as specified in the GlassFish documentation), I am getting the following trace:




Now If I remove the Transport Gaurantee setting from my web.xml, I get the following stack trace (where the Principals permission is still null but the hasUserDataPermission is true). This leads me to suspect that the prior trace was due to an SSL certificate error?




I have to two questions while I continue researching possible causes and solutions?

1) In Netbeans I set the 'Confidental' Transport Gaurantee in the web.xml which activates SSL (https) and throws the usual certificate error before displaying the login page. Could this be responsible for the failed permission errors in the stack trace?

2) Do I have to create the connection pool in the GlassFish Admin console or is it sufficient to create a JDBC resource file and conection pool, as well as PersistenceContextUnit in Netbeans and deploy this in the application?

I know that this resource file created in Netbeans is talking to the DB because I'm able to create users and roles in the admin part of my application
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21


I can neither get more information on these errors from the stack trace nor Am I finding much online. I have set the logging to FINEST so isn't this the most granular level of logging?


Nah. The most granular level is to yank down a copy of the source code and put it under a debugger. Which is probably what I'd be doing if I was stuck for so long on something like that. One of the advantages of using an open-source product. Especially now that closed-source paid product support is so often worthless.

You will have problems if you don't have your certs set up properly and you attempt to use secure transport. And a login screen should ALWAYS be secured (obviously!) It' even possible, since this is a server function, that the server forces secure transport for the login screens, regardless of what the app itself says. Whether or not that's part of your problem, I can't say. Ideally, there would be a more obvious message in cases like that. I'm not sure if by "the usual certificate error" you mean a warning on the client or an actual failure to access the cert/cert chain from the server's certificate store. Client-side warnings can usually be ignored for testing purposes. Heck, my local public libary has warnings in production (cert expired long ago). Then again they outsourced their emailing to an outfit in Belgium that cannot do basic HTML right. I've yet to actually be able to read an email from my library on any device I own. Maybe IE can handle it, but I don't do IE.

I'm not totally sure I understand question #2, but if it's what I think you're asking, the GlassFish Admin console sets deployment options, but what in J2EE terms is known as the server-specific deployment file can also do so. If that's what your "JDBC Resource file" is. The other deployment file (server-independent deployment file) is the webapp's WEB-INF/web.xml file, incidentally.
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

You gotta love creative outsourcing that creates colorful problems for today's practical solutions!

Looks like my problem is related to a JNDI naming exception. I set the debugger for the logincontext in the JVM option of the GlassFish domain.xml and got the following trace:



So I'm checking my xml config files are correct starting with glassfish-resources.xml (this is supposed to store the config information for the JDBC resource and connection pool AND YES THANKS FOR ANSWERING QUESTION 2):



Here I'm not sure of the conection pool name (securityDataSourcePool) should just be called securityDataSource and this is the reason GF is unable to look up the JNDI?

Then the glassfish deployment descriptor glassfish-web.xml only contains role mappings:



web.xml seems like it correctly refers to the correct JDBCRealm



The realm configurations in the GF admin console are:

realm name: jdbcrealm
JAAS Contetx: jdbcRealm
JNDI: jdbc/securityDataSource
User Table: users
Username column: username
Password column: password
Group Table: groups
Group Table UN column: username
Group name col: groupname
password encryption algorithm: none

So far I can't see the cause of the JNDI conflict from these files but i'm sure I'm missing something
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21

The name "securityDataSourcePool" is what connects the jdbc-resource to the jdbc-connection-pool so that's fine.

However, I do have doubts about the jdbc-connection-pool definition. It defines values for parameters "User", "Password" and "URL". In most systems, those would be lower-case names, and Java stuff is almost invariably case-sensitive, so unless the GlassFish connection pool construction is different, that would mean that effectively you would have defined a pool to nowhere with no security credentials. The only reason I'm not more assertive about that is that I'm understanding that the original copy of that file was constructed by the GlassFish admin GUI, which is supposed to know what's right.

There's a fourth parameter that database connections normally require and it's missing. That's the fully-qualified classname of the JDBC driver that must be used. It's important since most J2EE servers don't come with JDBC drivers wired into them, and even if they did, a lot of databases have more than one driver, either because they have difference performance features or they come from third parties or both.

Once again, hitting the obvious, the driver must be installed in GlassFish itself and NOT in the WAR for this to work properly. People do sometimes make that mistake.
Jay Tai
Ranch Hand

Joined: Apr 25, 2012
Posts: 169

OK one odd thing I noticed was the pool settings were duplicated:

User
Password
URL
user
password
url

  • I deleted the Uppercase values, flushed the connection pool, pinged the connection, both successful


  • Ensured the mySql driver was installed in the GF domain/domain1/lib


  • Undeployed the app and stopped the server


  • Adjusted the resource file so only small case letters are there


  • Restarted the server


  • SAME ERROR!

    I also read somewhere that using generic names like users and groups for the tables causes conflicts. I'm going to try and change those but can something like the table names cause a JNDI conflict? Isn't that more likely to cause a sql exception?
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    Although details aren't clear, I think the JNDI error is coming from the fact that the connection pool isn't being created, hence there's nothing to store under the selected JNDI subtree, causing failure when an attempt is made to retrieve what isn't there.

    You didn't mention providing a driver class, and I'm very doubtful that GlassFish can reliably infer what class to use - assuming it wants to infer anything at all.

    I should have bounced this to the GlassFish forum, because what we really need is some input from people who regularly configure GlassFish. So I'm going to move this topic over there.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    Good idea. When posting this I couldn't decide if it was a GF or JSF problem. I don't follow why GF has to infer anything about the driver. When creating the jdbc resource and connection pool I am given an option to use an existing DB connection which is a mySql schema. When i checked the GF domain/domain1/lib directory after creating the connection pool I saw the mySql Connector J drive in there. Where would I specify the right driver to use and doesn't the mySql driver in the domain directory mean that GF has inferred mySql is the default?
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    Usually, the driverClass is one of the 4 parameters that define a connection or connection pool. There's no guaranteed way to determine the "right" class, however. Some driver jars contain multiple drivers sharing common code, especially those that support both regular and extended transactions. Some drivers you don't WANT pulled in by default. A couple of years ago, Microsoft's SQL Server JDBC driver did a really botch-up job of handling transactions and I had to use a third-party SQL Server driver (open-source from sourceforge.net) to make the app functional. The Microsoft driver has been fixed since then, but at the time, it was impossible.

    So that's why red lights flash when I don't see an explicit driver class specified as part of the pool definition.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    I totally see where you're coming from but I can't find where I would have to put the driver. When creating the resource and connection pool there doesn't seem to be any option to specify the driver unless I add the driver as a property. I hesitated to do that because j_security_check seems to be such a fussy 'framework' in terms of keeping to best practices. But I seem to have gone 'by the book' so please let me know where I should define the driver and I'll see if this solves the problem.

    In the GF Admin console under Connection Pool there is an option to add the driver classname, but it's greyed out and I can't enter any values there!

    Thank you!
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    The driverClass is normally one of the parameters provided along with the database URL, user ID and password.

    You aren't having problems with container-managed security as far as I can tell, you're having problems with your database connection pool. The security issues because you're using a Realm that requires a proper database connection, so if you can fix that, likely the security issues will clear up.

    If Glassfish is like Tomcat, there should be a Realm that can get the userid/password and userid/roles from a flat or XML file. That's often a useful way to test security when you don't have the ability to connect to the production security framework. Since Realms are plug-compatible, no application changes are required. So you might want to try that while we're waiting for someone to reveal why you appear to have basic database issues.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    I think Tomcat is a bit simpler and more lightweight but I have to use GF for this project.

    On GF I see a realm defined in the web.xml and the glassfish-resources.xml and a reference to the DataSource in the persistence.xml where I am able to run JPQL queries. Apart from that I don't see anywhere where I can unit test the realm. I'll keep looking.
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    Tomcat is simpler. But in the matter of container security, it's fully-compliant. What I was getting at was that since Tomcat has a simple Realm that's useful for testing and other lightweight security needs, it wouldn't surprise me if Glassfish did too. In fact - just a minute - http://docs.oracle.com/cd/E18930_01/html/821-2435/ggkuk.html - it's called the File Realm, and it's the default.

    Glassfish actually calls them Authentication Realms or Security Domains. Hopefully the term "Authentication Realm" isn't literal, since a Realm typically provides both Authentication (login) and Authorization (role checking). A quick scan of the docs would give the impression that you actually needed to map roles to user IDs in the deployment descriptor, but I hope that isn't the only way, since it would quickly become unmanageable. Better to define the user role mappings in a database, LDAP directory or other large-capacity external storage. And again, if Tomcat does it (and it does), I'd expect Glassfish to be able to do so.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    I see what you mean now. I've actually used the file realm in another application. I can test this in the file realm but I suspect, as you said, my problem is probably with the connection pool. Here is another problem I came across with regards to the driver for the connection pool. When you create a resource and connection pool in Netbeans you don't have the option to specify the driver. The pool just uses an existing connection with an already specified driver. If you create a pool from the GF admin console then try to create a resource from the IDE (Netbeans), the connection pool created from GF admin console (after restarting the server) is not detected by the IDE.

    So my first question is, how do you create a connection pool and jdbc resource where the driver class can be specified?



    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    NetBeans isn't going to be around when the server runs in production. You need to determine how to define the connection pool strictly via Glassfish.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    True but I still need to get the GF admin console setting recognized by the Netbeans config files in order to deploy the application correctly. Right?
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    Only if you are dependent on NetBeans to do your deploying for you. An IDE is supposed to help you develop, not be an essential part of the production process.
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    OK so I followed your advice and created the connection pool and resource strictly in the GF server, instead of creating 'portable' resource and CP configuration files in Netbeans. I'm still using web.xml to refer to the jdbc-realm. Doesn't look like I'm getting a NameNotFoundException anymore. Instead I'm getting a more mysterious error:



    This suggests that the Connection Pool might now be getting read by the application. I'm suspecting that the error might be a result of the user and role mappings. When I got rid of the Netbeans configuration files and created everything on the actual server, it also meant that I had to get rid of the glassfish-web.xml descriptor, since that file depends on the other configuration files. So should I be mapping the users and roles from web.xml? Could this be the cause f the above error?
    Tim Holloway
    Saloon Keeper

    Joined: Jun 25, 2001
    Posts: 16142
        
      21

    web.xml is the container independent deployment descriptor. It defines the URL patterns and roles and how they interrelate.

    The other half of that equation is the container dependent deployment descriptor. In Tomcat, that would be the Context file. I'm not sure what it is in Glassfish, and I keep hoping someone who knows will jump in and help.

    You don't map users and their assigned roles or even database tables and columns in web.xml because the Realm is defined to the Container (Glassfish), not to the webapp. By keeping those details out of web.xml, the Realm can be changed - say from jdbc to a file or LDAP database without requiring any changes in the webapp itself (including web.xml).
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    I'll consult the GF documentation but I recall glassfish-web.xml is where the user and role mapping took place previously and it automatically detects the security roles from web.xml but you need to create the mapping relationship in that file. I don't see any reason why I can't keep that file even if I'm not creating jdbc resources within the application. Assuming glassfish-web is the 'dependent' file, could excluding this be the cause of the exception in my last post?
    Jay Tai
    Ranch Hand

    Joined: Apr 25, 2012
    Posts: 169

    Update - hearing about various rumours of GF 4 having bugs and problems with connection pools, I donwgraded to GF 3. I followed the GF documentation and online resources, re-created all my resources (including connection pool), placed the mySql driver in the gf/domains/domain1/lib. I got the below error, changed the location to gf/lib, error, changed location to gf/domains/domain1/databases. The below error is still there:



    The ping fails too on GF 3 with the same error, but ping works on GF4. Looking online, GF connection pooling seems to be riddled with problems!
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: j_security_check failing to authenticate users in JSF application