Switching to the JDBC realm worked great. Hear are some scribbles I jotted down while switching in case it helps someone else who stumbles upon this thread trying to do the same thing. Note I'm not sure if I kept these notes 100% up to date, they could have something I backed out and they could be missing something:
Create pool.
Name: userauth
Resource Type: javax.sql.DataSource
Database Vendor: JavaDB?, I picked Derby instead
Needed to add these properties to the pool:
databaseName=userauth
Password=<your systems password here>
connectionAttributes=;create=true
already defaults:
User=APP
ServerName=localhost
PortNumber=1527
Make sure you can ping it.
Create JDBC resource.
JNDI Name: jdbc/userauth
Pool Name: userauth <- Needs to match pool name above
Description: User Authentication
Status: enabled
Create Realm:
Name: userauth
Class: *.JDBCRealm
JNDI: jdbc/userauth <- Needs to match resource above
User Table: USERTABLE
User Name Column: USERID
Password Column: PASSWORD
Group Table: GROUPTABLE
Group Name Column: GROUPID
Assign Group:
Database User: APP
Database Password: <your systems password here>
Digest Algorithm: MD5
Encoding:
JAAS context: jdbcRealm
(Plan to try removing username and password from connection pool, I think they are redundant if they are listed with the realm)
Add a new database connection in netbeans:
Java DB (Network)
the derby driver
jdbc:derby://localhost:1527/userauth
User Name: APP
Password: <your systems password here>
Run a *.sql file to create tables and first users:
-- Create tables for JDBC realm
CREATE TABLE USERTABLE (
USERID VARCHAR(32) NOT NULL CONSTRAINT USER_PK PRIMARY KEY,
PASSWORD VARCHAR(32) NOT NULL
);
CREATE TABLE GROUPTABLE (
USERID VARCHAR(32) NOT NULL,
GROUPID VARCHAR(32) NOT NULL,
CONSTRAINT GROUP_FK PRIMARY KEY(USERID, GROUPID),
CONSTRAINT USER_FK FOREIGN KEY(USERID) REFERENCES USERTABLE(USERID)
ON DELETE CASCADE ON UPDATE RESTRICT
);
CREATE TABLE USERINFOTABLE (
USERID VARCHAR(32) NOT NULL,
FIRSTNAME VARCHAR(32),
LASTNAME VARCHAR(32),
EMAIL VARCHAR(100),
CONSTRAINT USERINFO_FK FOREIGN KEY(USERID) REFERENCES USERTABLE(USERID)
ON DELETE CASCADE ON UPDATE RESTRICT
);
INSERT INTO USERTABLE(USERID,PASSWORD) VALUES ('bankadmin', <insert scrambled password here>);
INSERT INTO GROUPTABLE(USERID,GROUPID) VALUES ('bankadmin', 'bankAdmin');
INSERT INTO USERINFOTABLE(USERID,FIRSTNAME,LASTNAME,EMAIL) VALUES ('bankadmin', 'delete or edit me', 'blabla', '');
INSERT INTO USERTABLE(USERID,PASSWORD) VALUES ('200', <insert scrambled password here>);
INSERT INTO GROUPTABLE(USERID,GROUPID) VALUES ('200', 'bankCustomer');
INSERT INTO USERINFOTABLE(USERID,FIRSTNAME,LASTNAME,EMAIL) VALUES ('200', 'delete or edit me', 'blabla', '');
To get the scrambled password, I used this code (don't include the "MD5: " prefix in the database):
package com.sun.tutorial.javaee.dukesbank.util;
import java.security.MessageDigest;
import java.math.BigInteger;
public class OneWayHashPerformer
{
public static void main( String args[] ) throws Exception
{
String s = "<plaintext password here>";
MessageDigest m = MessageDigest.getInstance( "MD5" );
m.update( s.getBytes(), 0, s.length() );
System.out.println( "MD5: " + new BigInteger( 1, m.digest()).toString( 16 ) );
}
}
To specify the realm, modify the appropriate deployment descriptor for your application:
Added this to sun-web.xml (in dukesbank-war) and to sun-ejb-jar.xml (in dukesbank-ejb under the sun-ejb-jar element):
<security-role-mapping>
<role-name>bankAdmin</role-name>
<group-name>bankAdmin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>bankCustomer</role-name>
<group-name>bankCustomer</group-name>
</security-role-mapping>
Change realm name from file to userauth under web-app\login-config\realm-name in web.xml (in dukesbank-war).
sun-application.xml for the top level project (holder of all three sub projects):
Was already mapped groups to roles.
Add realm element to it:
<realm>userauth</realm>
Perhaps sun-ejb-jar.xml doesn't need a realm because the calls are local and not via web services (not to be confused with web client). Or it’s covered by the top level sun-application.xml file.
------
Some related links:
http://docs.sun.com/app/docs/doc/819-3660/6n5s7klpf?a=view
http://docs.sun.com/app/docs/doc/819-3671/abloe?a=view
http://docs.sun.com/app/docs/doc/819-3672/beabr?a=view
http://docs.sun.com/app/docs/doc/819-3673/6n5sk1d5b?a=view
http://java.sun.com/javaee/5/docs/tutorial/backup/doc/Security-JavaEE3.html
http://developers.sun.com/appserver/reference/techart/as8_authentication/index.html
http://java.sun.com/javase/technologies/security/
http://blogs.sun.com/foo/entry/mort_learns_jdbc_for_glassfish
http://blogs.sun.com/foo/entry/mort_learns_jdbc_realm_authentication
http://codepimpsdotorg.blogspot.com/2007/12/glassfish-jdbc-realm-authentication.html
http://blogs.sun.com/swchan/entry/jdbcrealm_in_glassfish
http://www.sun.com/software/dtd/appserver/
-----
Later I did this to switch which databases is used for passwords:
Switch databaseName in userauth connection pool from userauth to sun-appserv-samples
Removed SecurityMechanism=4 (fixed a wrong username/password issue)
Realm's JNDI references JDBC Resource JNDI which specifies which connection pool to use which must have the correct database name, so it must stay as userauth.
Note that I think none of the database references in netbeans reference the JDBC resource JNDI's. They are "database URL's" in the form of jdbc:derby://<HOST>[:<PORT>]/databaseName[;attr1=value1[;...]]
The APP_dukesbank-ejb.dbschema file also uses a database URL
Connection pools may only be getting used by web clients (and web services too perhaps).
[Message sent by forum member 'markkr2' (markkr2)]
http://forums.java.net/jive/thread.jspa?messageID=294920