I recently ran into the problem that the Roles I declared in my application were never assigned to the users I defined, when deployed in my Glassfish server. The log provided me with the following:
2016-03-30T13:13:43.560+0200] [glassfish 5.0] [WARNING] [] [javax.enterprise.system.core.security] [tid: _ThreadID=96 _ThreadName=AutoDeployer] [timeMillis: 1459336423560] [levelValue: 900] [[
No Principals mapped to Role [player].]]
Upon closer inspection, the problem became quite clear.
A more in-depth explanation on how security works in Glassfish can be found in the Java EE 6 Tutorial at [1].
Within a realm (security policy domain) you can define groups and users. Users can be assigned to groups.
Now, there needs to be a mapping between the security as defined in your application, and the security as defined in your application server. There is a bit of a separation between the two, because you need to be able to effortlessly deploy your application to different application servers without having to change your applications security settings.
Even if the realm of the application server happens to be configured differently.
scope | security items | Annotations | deployment descriptor |
within your application | roles | @DeclareRolls, @RolesAllowed | web.xml |
within your application server | users and groups | - | glassfish-web.xml |
Manual mapping
Manual mapping between groups/users and your applications defined roles, is by using an application server specific deployment descriptor. The one glassfish uses is the WEB-INF/glassfish-web.xml and is included in your application war.
Schematically it looks like the following:
An example of the glassfish-web.xml deployment descriptor:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<context-root>/myNewWebapp</context-root>
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>god</role-name>
<principal-name>root</principal-name>
<group-name>god</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>player</role-name>
<group-name>player</group-name>
</security-role-mapping>
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>
In the example above most mappings are between groups and roles. There is one exception, which is the principal (user) "root". He is directly mapped to the "god" role, as he should be.
Automatic mapping
One of the handy features if you wish to use it, is the option for the glassfish server to automatically try to map groups and roles, based on similar names. This can be done in the glassfish administration gui, by going to server-config and selecting security.
It can completely replace the need for a glassfish-web.xml deployment descriptor.
References
- [1] Java EE 6 Tutorial - Working with Realms, Users, Groups and Roles
- https://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html