4
votes

Using glassfish 3.1.1 for a Java EE6 project the security role mapping as defined in glassfish-web.xml has no influence on the 'user - role' mapping.

Calling request.isUserInRole("USER") as well as request.isUserInRole("ADMIN") always returns false.

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>

Annotating LoginBean.java with @DeclareRoles as shown below, the roles are assigned as expected.

LoginBean.java

...
@DeclareRoles({"ADMIN", "USERS"})
@Named(value = "loginBean")
@RequestScoped
public class LoginBean implements Serializable { ...

Why do I need the @DeclareRoles in LoginBean.java in order to get a working 'user - role' mapping for request.isUserInRole?

2

2 Answers

4
votes

A similar question on Coderanch cites 17.2.5.3 Declaration of Security Roles Referenced from the Bean’s Code of the EJB 3.1 specification:

The Bean Provider is responsible for using the DeclareRoles annotation or the security-role-ref elements of the deployment descriptor to declare all the security role names used in the enterprise bean code. The DeclareRoles annotation is specified on a bean class, where it serves to declare roles that may be tested by calling isCallerInRole from within the methods of the annotated class. Declaring the security roles allows the Bean Provider, Application Assembler, or Deployer to link these security role names used in the code to the security roles defined for an assembled application.

[...]

If the DeclareRoles annotation is not used, the Bean Provider must use the security-role-ref elements of the deployment descriptor to declare the security roles referenced in the code.

(Emphasis mine)

So it's just a simple hint to the Deployer and they don't have to interpret the code to get the list of the used roles. It could be really hard if a developer calls the isUserInRole() method with a role name which comes from an other method or from a very complex logic.

This also could be useful (from 17.3 Responsibilities of the Bean Provider and/or Application Assembler):

The main reason for providing the security view of the enterprise beans is to simplify the Deployer’s job. In the absence of a security view of an application, the Deployer needs detailed knowledge of the application in order to deploy the application securely. For example, the Deployer would have to know what each business method does to determine which users can call it. The security view defined by the Bean Provider or Application Assembler presents a more consolidated view to the Deployer, allowing the Deployer to be less familiar with the application.

(I see that the question is about a web application but I think the reasoning behind is the same and servlet spec isn't so detailed.)

From Deployer’s Responsibilities: Assignment of Security Roles (17.4.2):

The Deployer assigns principals and/or groups of principals (such as individual users or user groups) used for managing security in the operational environment to the security roles defined by means of the DeclareRoles and RolesAllowed metadata annotations and/or security-role elements of the deployment descriptor.

So, according to the spec the glassfish-web.xml is created by the Deployer (not the Bean Provider or Application Assembler) and for the Deployer's work he needs the role names from "DeclareRoles and RolesAllowed metadata annotations and/or security-role elements of the deployment descriptor."

1
votes

The role-mapping in the glassfish-web.xml translates a Java EE application's security role names into a deployment environments user/group mechanism. The roles are abstract... and until your application uses a role, the mapping is unnecessary and not consulted.