This is my first post here. I would have two questions regarding Java EE declarative security: (1) file-based authentication and (2) database-based authentication. I have included the relevant parts of the configuration for both questions. I am running code on Glassfish 3.1.1. Thank you for your help and in advance.
I also looked for answers to my questions and found some useful examples, which I also put at the bottom of the post. I tried to follow them, so the current configuration state may contain data from these samples, but they do not solve the problem.
-File authentication works correctly if the "default mapping to the main role" is checked, otherwise it did not work, even if a principle was added to the mapping. Maybe I configured something wrong.
-DB authentication. This did not help, since group names could not be read. See Details below. Authentication works correctly, that is, the user is recognized. I even tried renaming tables to avoid potential name collisions with some Glassfish internal stuff ...
(1) File- based authentication: File realm, 2 users: user, administrator added and assigned to groups: user and administrator (configuration / server-config / security / realms / file → User management)
configuration / server configuration / security Default Default To Role Mapping "ticked" → it works Default Principal To Role Mapping "ticked" → it does not work even if it is added to the security association.
web.xml [...] <security-constraint> <display-name>Admin Pages</display-name> <web-resource-collection> <web-resource-name>Protected Admin Area</web-resource-name> <description/> <url-pattern>/faces/admin/*</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>admin</role-name> </auth-constraint> </security-constraint> <security-constraint> <display-name>User Pages</display-name> <web-resource-collection> <web-resource-name>Protected Users Area</web-resource-name> <description/> <url-pattern>/faces/users/*</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>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>file</realm-name> <form-login-config> <form-login-page>/faces/loginForm.xhtml</form-login-page> <form-error-page>/faces/loginError.xhtml</form-error-page> </form-login-config> </login-config> [...]
glassfish-web.xml: <glassfish-web-app> <security-role-mapping> <role-name>admin</role-name> <group-name>admin</group-name> </security-role-mapping> <security-role-mapping> <role-name>user</role-name> <group-name>user</group-name> </security-role-mapping> </glassfish-web-app>
Recorded errors without standard default display:
- There are no members mapped to the [user] role.
- There are no members mapped to the [admin] role.
Log without the default principal mapping: <security-role-mapping> <role-name>admin</role-name> <group-name>admin</group-name> <principal-name>admin</principal-name> </security-role-mapping> <security-role-mapping> <role-name>user</role-name> <group-name>user</group-name> <principal-name>user</principal-name> </security-role-mapping>
The recorded errors without a standard default mapping: 1. There are no members mapped to the [user] role. 2. There are no members mapped to the [admin] role.
(2) Database Based Validation:
The kingdom has changed the specified area to jdbcRealm in web.xml
1) mn (many-to-many relationship between user and group table)
SEC1111, Unable to load group for JDBC domain user [tamas].
2) the same for 1-n (one-to-many relationship between the users and groups table)
SEC1111, Unable to load group for JDBC domain user [tamas].
3) the group name in the same table as the username and password
SEC1111, Unable to load group for JDBC domain user [tamas].
Kingdom Configuration: (I also tried to leave “Assign Groups” blank or fill in “default”, but the result was the same.)
Image had to be omitted, summary: JAAS context: jdbcRealm JNDI: jdbc/securityDataSource User Table: TBLUSERS User Name Column: USERNAME Password Column: PASSWORD Group Table: TBLGROUPS Group Name Column: GROUPNAME Assign Groups: default Digest Algorithm: none
DB ER Relationship Diagram mn:
The image should be omitted, but as a compensation :-) below you will find an SQL script.
SQL Script: SET @ OLD_UNIQUE_CHECKS=@ @UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @ OLD_FOREIGN_KEY_CHECKS=@ @FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @ OLD_SQL_MODE=@ @SQL_MODE, SQL_MODE='TRADITIONAL'; CREATE SCHEMA IF NOT EXISTS `jdbcrealm` ; USE `jdbcrealm` ; -- ----------------------------------------------------- -- Table `jdbcrealm`.`TBLUSERS` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jdbcrealm`.`TBLUSERS` ; CREATE TABLE IF NOT EXISTS `jdbcrealm`.`TBLUSERS` ( `USERID` INT NOT NULL AUTO_INCREMENT , `USERNAME` VARCHAR(30) NOT NULL , `PASSWORD` VARCHAR(45) NOT NULL , UNIQUE INDEX `USERNAME_UNIQUE` (`USERNAME` ASC) , PRIMARY KEY (`USERID`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `jdbcrealm`.`TBLGROUPS` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jdbcrealm`.`TBLGROUPS` ; CREATE TABLE IF NOT EXISTS `jdbcrealm`.`TBLGROUPS` ( `GROUPID` INT NOT NULL AUTO_INCREMENT , `GROUPNAME` VARCHAR(30) NOT NULL , PRIMARY KEY (`GROUPID`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `jdbcrealm`.`USERS_GROUPS` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jdbcrealm`.`USERS_GROUPS` ; CREATE TABLE IF NOT EXISTS `jdbcrealm`.`USERS_GROUPS` ( `USER_USERID` INT NOT NULL , `GROUP_GROUPID` INT NOT NULL , PRIMARY KEY (`USER_USERID`, `GROUP_GROUPID`) , INDEX `fk_USER_has_GROUP_GROUP1` (`GROUP_GROUPID` ASC) , INDEX `fk_USER_has_GROUP_USER` (`USER_USERID` ASC) , CONSTRAINT `fk_USER_has_GROUP_USER` FOREIGN KEY (`USER_USERID` ) REFERENCES `jdbcrealm`.`TBLUSERS` (`USERID` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_USER_has_GROUP_GROUP1` FOREIGN KEY (`GROUP_GROUPID` ) REFERENCES `jdbcrealm`.`TBLGROUPS` (`GROUPID` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB; SET SQL_MODE=@OLD _SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD _FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD _UNIQUE_CHECKS;
I copy here a few interesting links on a topic that were useful to me. Initially, I followed the second. Other people may also find them useful.
Thank you for reading. Best wishes,
Tamash
Part 2 Thanks for the answers. I created 2 new table users and a one-to-many group. On the Realm configuration page, I set table names and columns for username, pwd and groups. Matt comment also matches the link (see below, I cannot post it here)
[...] The interesting part here is that for the user table and group table, I used v_user_role as the value of the property. v_user_role is a database that contains information of both the user and the group. The reason I did not use the user table directly, because glass fish assumes that both the user table and the group table contain a column containing the username and this will lead to duplication of data. [...]
-- ----------------------------------------------------- -- Table `jdbcrealm`.`user` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jdbcrealm`.`user` ; CREATE TABLE IF NOT EXISTS `jdbcrealm`.`user` ( `userid` VARCHAR(30) NOT NULL , `password` VARCHAR(45) NOT NULL , PRIMARY KEY (`userid`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `jdbcrealm`.`group` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jdbcrealm`.`group` ; CREATE TABLE IF NOT EXISTS `jdbcrealm`.`group` ( `groupid` VARCHAR(30) NOT NULL , `userid` VARCHAR(30) NOT NULL , INDEX `fk_group_user1` (`userid` ASC) , CONSTRAINT `fk_group_user1` FOREIGN KEY (`userid` ) REFERENCES `jdbcrealm`.`user` (`userid` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;
The same error occurs. I also tried in such a way that I put the primary key in the column of columns in the group table, but I did not change it in terms of the question. It is also interesting that I tried to do the same with 1 table, which contains usernames, pwds, groups and the same error.
Towards a solution and solution
Comments from Matt have helped a lot thanks to these great posts. So, in the beginning, when I wrote a question related to database-based authentication, it was clear that user groups could not be loaded. This was reported by an error message on the .log server.
However, my suspicion turned to links between tables and column names. However, after simplifying the data model for user group objects, I could not explain why it does not work even with a simple table containing the user, pwd, and group. I continued the investigation in this direction. I suggested that column names can influence this. When I applied the Matt configuration, the message “failed to load groups” disappeared from the .log server, but the phenomenon remained the same. Therefore, I suggested that groups might already be loaded, but there is another problem. Then I accepted the Matt configuration and started changing the column names step by step to get to the original configuration, but the message “cannot load groups” did not appear in the log. When I reproduced the case with my initial settings, and the log message was not there, I knew that something was wrong with the registration, which he somehow disabled. So I started exploring the whole configuration.
When I looked at the deployed application, I selected deployment descriptors and loaded them on top of the glass fish console. web.xml was fine, it had the same content that I wrote, but glassfish-web.xml had completely different content ! It was generated as if I did not have glassfish-web.xml. Then I noticed that my glassfish-web.xml was not placed in the WEB-INF directory . I moved it there and did "clear everything, build" and deployed the application. Subsequently, I returned to the db view, which presents data between TBLUSERS and TBLGROUPS in many ways. I like this solution the most because it shows the clearest image in terms of data. I set the appropriate columns on the area configuration page. I tested it with two users: "tamas" and "arpi". "tamas" was added to user groups and administrators, meanwhile, "arpi" was added to the user group. The mapping between roles and user groups is in the glassfish-web.xml file. Access was granted to tamas for user and administrator resources, and arpi only got access to user resources.
Thanks for the help. Tamas