Mort Learns JDBC Realm Authentication for GlassFish
Here is another good blog on this subject.
In my last blog I showed you how to make a jdbc-resource that you can use for accessing a database.
Now I'll explain how to use that jdbc-resource to setup JDBC Realm Authentication and Authorization.
Realm Background
The job of a realm is to maintain a repository of user information. Each user has one password and 0 or more groups that he belongs to.
At runtime a Realm is initially given a username and password and the realm then figures out if the user is authentic by checking the password. It checks for authorization by seeing if the user's list of groups is authorized to use a resource (more on this later).
How to Create The Realm for userauth
Using Admin GUI navigate to Configuration/Security/Realms. Press the "new" button

Pick the classname that ends in JDBCRealm. Use the jndi name of your jdbc-resource -- if it isn't userauth.
I'm assuming that you are starting from scratch with no user database. If you already have such a database, you need to make sure your database table and column names are entered correctly and that your tables correspond to what JDBCRealm needs. Such details are coming up...
Tip: Use the names in the screen-shot for the 2 table names and 3 column names. These names are as good as the next. If you standardize on these names you can use some tools I've developed for help administering and testing the realm.
Database user and password -- I'm not so sure about this. The connection you get from the jndi name already has the username and password for that database. I put the username and password from my database here and everything worked fine...
Digest Algorithm
You have to decide whether to save passwords as clear-text or encrypted. If you want clear-text, leave the edit field blank. If you want your passwords encrypted set this field to MD5.
My recommendation is to use MD5 for the passwords. I have some tools with the code you need to convert a plain text password to an encrypted string in the right format for JDBCRealm.
On the other hand you can set it to no encryption -- and it will be much easier to seed the tables with test user info. You can always change it to MD5 later when you have everything working.

All of the GlassFish administration work is now done.
Now you need to add some tables to your database. You can run this sql script and it will do all the work for you. The script also adds one user with username=admin and password=admin.
The easy way to do this is to run "ij" -- a javaDB sql console -- there is a copy here: <gf>/javadb/bin
ij> connect 'jdbc:derby://localhost:1527/userauth;user=APP;password=APP;create=true';
ij> run 'createdb.sql';
Now it's time to try out a protected web module. What we want here is the World's Simplest Web Module.
In NetBeans, create a new web module. The web module consists of one hello world jsp file. Perfect. If you don't use NetBeans then create some sort of ultra simple web module.
We have to add quite a bit of stuff to web.xml. Netbeans makes fast work of it:

Here are the additions to web.xml (generated by NetBeans)
<security-constraint>
<display-name>Constraint1</display-name>
<web-resource-collection>
<web-resource-name>protected</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>ADMINISTRATORS</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>userauth</realm-name>
</login-config>
<security-role>
<description/>
<role-name>USERS</role-name>
</security-role>
<security-role>
<description/>
<role-name>ADMINISTRATORS</role-name>
</security-role>
</web-app>
I have 2 roles named "ADMINISTRATORS" and "USERS". I use these same names as the groupid values in the database table. This makes the role-mapping a bit easier because you use the exact same name on both ends.
You must setup the roll-mapping in sun-web.xml The easiest way to do it so directly edit the file and add these lines:
<security-role-mapping>
<role-name>USERS</role-name>
<group-name>USERS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ADMINISTRATORS</role-name>
<group-name>ADMINISTRATORS</group-name>
</security-role-mapping>
Build and deploy this web module and then run it. It will ask you for authentication info. If you enter "admin" "admin" you should be allowed in to see the jsp page.
If you enter the name and password for someone that does not belong to the group "ADMINISTRATORS" then you will get an access violation error.
If there is interest, I'll follow up with some tools you can use to add users dynamically and to manage the database itself.
I am on a steep learning curve, ran samples on JBoss, Tomcat (5 and 6) and now GlassFish (bundled with Netbeans 6.0 Beta). Any chance of providing some guidance on how this can be done with Netbeans only, i.e. putting all the configuration in the web.xml file may be. I am new to a lot of things, hence the steep learning curve :(
Posted by George Mutale on October 11, 2007 at 09:09 AM PDT #
I didn't even know that there was 'something sitting on this port'
http://localhost:4848/asadmin
I am that new that almost all the questions I ask will sound silly. Now that I have access to the app server interface, I will try out the info. that you have provided on the page. Thanks.
Posted by George Mutale on October 11, 2007 at 09:26 AM PDT #
Excellent question. I found out that there is a non-GUI way to add resources. You create an xml file and then use the CLI (asadmin) to create the resources.
I've never done it. I will research it and blog about it if you leave another comment here requesting it.
Posted by Byron Nevins on October 11, 2007 at 03:00 PM PDT #
Thanks. That will be great. There seems to be so many ways of doing things and so many examples using different application servers and frameworks, :(
For now I am sticking with Hibernate, JSF, Netbeans and GlassFish.
Thanks for your help.
Posted by George Mutale on October 12, 2007 at 01:25 AM PDT #
Did you encounter any kind of login exception while doing this?
I have my web application correctly setup and using a file realm. Switching to a jdbc realm always gives me the following error:
Web login failed: Login failed: javax.security.auth.login.LoginException: Security Exception
Posted by Patrick Julien on November 28, 2007 at 09:57 AM PST #
Once I got it working -- I don't see any errors.
What did the log message in server.log say?
There is a bug in the Realm code -->If it gets a SQL Exception containing the precise problem description -- it throws away the Exception and gives you a useless generic message instead.
If you turn up the logging to FINE -- you will see these SQL errors.
Posted by 72.25.90.41 on November 28, 2007 at 10:20 AM PST #
The log message says exactly that:
"Web login failed: Login failed: javax.security.auth.login.LoginException: Security Exception"
I am in the process of bumping the log level to fine for security. I can see that "doPasswordLogin" fails but I can a useless login exception, can't see anything about SQL still.
Posted by Patrick Julien on November 28, 2007 at 10:24 AM PST #
Have it, the problem seems to be that clear text passwords do not seem to work with glassfish 2.
Doing the exact same thing but setting MD5 for the digest algorithm finally worked.
Posted by Patrick Julien on November 28, 2007 at 10:37 AM PST #
I sort of suspected that the digests had something to do with your problem.
Glassfish WILL work with plaintext -- you leave the Digest Algorithm: field blank for the realm.
In fact -- you may want to do that in this scenario:
Sometimes you send in the digest of the password via a cookie without user intervention. Now what you want to do is MD5 digesting on the client side. Then you tell the server side that the passwords are plaintext.
-- byron
Posted by 72.25.90.41 on November 28, 2007 at 10:56 AM PST #
What are necessary steps to setup programmatic login using jdbcrealm from scratch?
Posted by Arthur on December 16, 2007 at 10:30 AM PST #
Same problem: "JAAS authentication aborted.
SEC5046: Audit: Authentication refused for [valent].
doPasswordLogin fails
javax.security.auth.login.LoginException: Security Exception".
I don't use MD5. In DB the passwords is stored as plain text. I use Netbeans 6.
Posted by Vale on January 21, 2008 at 01:06 AM PST #
To Patrick Julien: It's because of there has to be 'none' keyword for plain-text passwords indtead of "nothing". Check out http://blogs.sun.com/swchan/entry/jdbcrealm_in_glassfish.
The 'none' keyword works for me with GlassFish v2.1-b11.
Posted by Petr Hadraba on February 19, 2008 at 09:17 AM PST #
If the authentication is used for a javaEE App-client, at the beginning, a default log-in dialogue is used. How can I use my custom log-in dialogue for authentication?
Posted by Hillol on September 09, 2008 at 02:22 AM PDT #
This has been great content and exactly what I have been looking for and racking my head against for days. I'm a new user webber and was wondering if there are any tutorials or help to add a logout to this. Session invalidate doesn't seem to work. Also any tricks to creating an registration form for this database?
Posted by Scott W on March 25, 2009 at 09:52 AM PDT #
To Scott W.
This should definitely log you out:
request.getSession().invalidate();
==========================
What do you mean by registration form? Try this and tell me if that is what you are interested in and I'll post the source code.
try it -- create an account...
http://www.bnevins.com/AuthAdmin/Registration
Posted by Byron Nevins on March 25, 2009 at 10:38 AM PDT #
thanks for the quick response!
request.getSession().invalidate();
isn't working for me on top of a logout page. It keeps the session logged in.
And yes a registration form like that is what I was referring to but I think I can figure that out, but that leads to another question,
How would you setup form login (so the user information is stored for the session) based around what you described above?
thanks again!
Posted by Scott W on March 25, 2009 at 12:09 PM PDT #
Hi,
I'm still a novice with Java and Glassfish. I'm using Netbeans 6.5 and I have an Enterprise Application that contains numerous Web Applications. I have successfully set up security for each of these web applications and I am in the process of creating another web application that acts as a "portal" for the entire enterprise app that will have hyperlinks to navigate to a selection of pages that are within the other web applications depending on the role of the user and whether they are allowed to visit those pages (the hyperlinks are rendered conditionally according to the user's role).
Each of the web applications are using the same realm, but whenever I log into the portal app, if I try to visit a page that is within one of the other web applications, I am still required to login again, I was hoping I would not have to since I already logged in to one application (the portal) using the same realm.
Posted by Brian M on April 17, 2009 at 10:17 AM PDT #
Sorry, accidentally posted before actually asking the question ;P
What I meant to ask is if it is possible to be able to visit any page in any web application under the same enterprise application without logging in multiple times if I use the same realm for each web application? Thanks in advance!
Posted by Brian M on April 17, 2009 at 10:20 AM PDT #
http://docs.sun.com/app/docs/doc/820-4496/beacq?a=view
Read the article on SSO (Single Sign On)
Posted by Byron Nevins on April 17, 2009 at 11:01 AM PDT #
Thanks Byron!
This works great, it does exactly what I was looking for, thanks again for your help and quick response, have a good one.
Posted by Brian M on April 17, 2009 at 11:58 AM PDT #
Thanks for this post - I'm just looking at using this to secure an app so very useful. The question I have is how can I pass back to the calling application the role/permissions which an authenticated user has been assigned?
In my particular case, I'm looking to deploy a Flex application on glassfish and but my app needs to know what permissions an authenticated user has. I can pass parameters into a Flex app via 'flashVars' but I don't know how to get the 'role-name' of a session.
Can this be obtained from the headers anyway?
Tks
Alex
p.s. this page from adobe shows how it can pick params up from a jsp request ..
http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_3.html
Posted by Alex Curtis on May 06, 2009 at 03:48 AM PDT #
Thanks a lot. It was really helpful.
Posted by Raihan Kibria on May 17, 2009 at 07:20 AM PDT #
I like this tutorial very much. It is one way I am considering for authentication in a project I am working on. I can't seem to get it to work though. I follow the directions the way the instructions/pictures show and enter the code where I think it should be. When I run the simple program with the db given in the example it seems to find the database because it says that it requires authentication but when I put in the username and password from the example I get an HTTP 401 error or else it just keeps asking for the user information over and over. I am using Netbeans 6.5 and GF server v 2 oh, and JDBC. I even went to "none" where the MD5 digest was and reset the password to just "admin" but still no luck. Where am I going wrong? Thanks in advance for any suggestions.
JW
Posted by Joy Wells on August 06, 2009 at 06:52 PM PDT #