Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Thursday, 21 May 2015

Hippo CMS with Spring Security

Hippo CMS already uses Spring for dependency injection as part of the HST framework used to develop websites. By default, it uses JAAS as its authentication mechanism and the CMS repository (via the HippoAuthenticationProvider) for authenticating login credentials and providing security roles for the authenticated user.

The existing website application already had in excess of 10 million users and there was no way that these users would be moved into the CMS repository. Fortunately Hippo can be configured with a custom AuthenticationProvider to use a database or LDAP service rather than the CMS repository for authenticating login credentials.

As part of the redevelopment of the website, the login UI was also redesigned. The default form based authentication uses the Hippo UI templates to render the login form. Again this was quite easy to replace with a custom login form template by following the online documentation [1].

At this point the development was looking good, the show and tell at the end of the first sprint demonstrated the new login story and the home page with integration to internal services for authentication and customer transactional data.

The next sprint required some changes to the login functionality based on insights gathered from user testing and UI/UX designers. Due to the business requirements, the login functionality was required to display a number of different messages depending on the cause of authentication failure. This may involve a simple error message, or asking the user that they need to activate their account or to contact the call centre if their account had been locked.

Using the default login mechanism proved to be difficult in propagating different error messages from the custom AuthenticationProvider back through the Hippo JAAS LoginModule and to the Hippo LoginServlet to render the login form. This was due to the Hippo LoginModule catching any exceptions from the AuthenticationProvider and throwing a new JAAS LoginException with a default error message thereby losing the error code and message from the original exception. There were also other issues with CSS when the login form was redisplayed after an authentication failure.

Furthermore, there was also a lurking requirement that the new mobile apps would be required to integrate with Hippo CMS for authentication and content. This would require developing a RESTful API to expose the content for the mobile apps to use. The mobile apps would not use http form based authentication for a RESTful API. Consequently the new website would need to provide a different authentication method depending on the access channel (web browser or mobile app).

The above issues and the complexity involved in customising the JAAS implementation were the main deciding factor to adopt Spring Security. Fortunately, we were not the first team that needed to do this and the Hippo community provides a project that details the integration of Spring Security with HST based website applications.[2]

The configuration is pretty simple and requires configuring the Spring Security filter within the web.xml file.

Spring Security Configuration in web.xml
This will now ensure all requests are passed through the Spring Security filter chain. The context files can be used to specify any security related Spring beans such as a custom authentication manager, authentication filters and success and failure handlers.

Thereafter, to integrate Spring Security within the HST based web application, it is simply a matter of adding the SpringSecurityValve into the HST request processing pipeline. As the HST pipeline employs the 'chain of responsibilty' pattern [3], by adding the SpringSecurityValve into the pipeline, HST will ensure the SpringSecurityValve has the opportunity to handle the request and establish a javax.security.auth.Subject if it finds a spring security Authentication instance.

The Hippo SpringSecurityValve allows securing the HST based website by configuring 'hst:sitemapitem' or 'hst:mount' nodes with security settings.

References
[1] http://www.onehippo.org/library/concepts/security/hst-2-authentication-and-authorization-support.html
[2] http://hst-springsec.forge.onehippo.org/
[3] http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

Tuesday, 3 September 2013

Runtime Configuration of log4j properties

log4j is used widely to provide logging in applications. There are numerous articles about how to configure log4j.properties or log4j.xml to enable/disable logging at various levels and categories. Often it is necessary to enable the debug log level for a short duration to identify the cause of a production issue. Without runtime configuration, this would require stopping the application, changing the log configuration (after extracting the properties file from the war) and then redeploying.

This post describes how log4j can be configured outside of the application and also changed at runtime.

File Watchdog

Log4j provides runtime configuration through the DOMConfigurator.configureAndWatch for XML files, or the PropertyConfigurator.configureAndWatch for properties file. Both these methods take the absolute path for the configuration file and a refresh interval. This allows the configuration file to be located outside of a web application war file and allow administrators to change the logging levels at runtime.

The configureAndWatch API can be invoked from a custom servlet listener. For users of the Spring framework, there already exists the Log4jConfigListener that is a wrapper to the Log4j configureAndWatch API. This listener is configured in the web applications web.xml.

Spring Log4jConfigListener

By specifying the log4jConfigLocation to a file outside the web application, it allows different environments (dev, test, prod) to have different levels of logging enabled. The log4jRefreshInterval specifies how often the log4j.properties file should be checked for changes and reloaded. This allows runtime changes to the log4j configuration to be performed.

JMX

Log4j also has built-in support for JMX and two classes org.apache.log4j.jmx.LoggerDynamicMBean and org.apache.log4j.HierarchyDynamicMBean are used to expose and register loggers as MBeans. However, it still requires wrappers to work to add loggers that are not defined at start-up.


Thursday, 11 July 2013

Environment Specific Configuration of Web Applications

We've all faced this situation. A web application needs to be deployed to a number of different environments (dev, test, prod) and each of these requires slightly different configuration such as which database to use etc.

Assuming a typical Maven-based Spring application, these configuration parameters are usually held within a properties file in the src/main/resources folder.

sample properties file









And then used to substitute place-holders within Spring application context files.

sample application context file

Now how do we provide environment specific configuration for every deployment?

  • Manually unpack the artefact and modify the properties file and then repackage it. This is clearly unacceptable from a maintenance and quality control perspective.
  • Use Maven profiles to include an environment specific properties file at build time.
  • Use Maven filtering in combination with profiles to produce an environment specific build.
  • Use Maven assembly plug-in to generate multiple environment specific artefacts in a single build.
  • Use Spring profiles for runtime configuration

Our initial approach was to use Maven filtering with profiles and further augment the artefact by using the profile id as a classifier.

Maven filters
There exists a properties file for every required environment (dev, test, prod), but instead of placing these files within the src/main/resources directory, they are placed within the src/main/filters directory. The property files follow a naming convention such as config-{profileid}.

Maven pom filtering configuration






















The above Maven pom extract specifies that when the resources are copied from the source to target directory, place-holder substitution or filtering will take place using the environment specific filter. The artefact that is built with the maven-war-plugin will also be tagged with the environment variable (env).

The env variable is a Maven property that is set by the active profile.
Maven profiles






































The above Maven pom extract specifies a number of profiles that simply set the env property, that effectively points to a configuration file that contains all the properties. This is a cleaner approach than to list all the environment specific properties within the Maven profile.

The above approach works perfectly well but there are still some deficiencies such as:

  • Requires running the build multiple times for environment specific builds. This is not recommended as the artefact should be built only once and deployed anywhere.
  • Doesn't work well with the Maven release plug-in and automated build tools.
  • Every new environment requires a new profile, new configuration filter and a new artefact.
Taking a step back, we first need to identify and understand the problem we are trying to solve. 

Ideally the configuration should not be tightly coupled to the build but external and applied at runtime. By storing the configuration property file outside of the application in a specified location on the deployment environment, the application can be configured with environment specific properties at runtime.

External Runtime Configuration
This is achieved simply by configuring the Spring application context property-placeholder to load properties from a file location that is outside the application. Note, that there is also a properties file in the application (src/main/resources), that is used to apply default properties. The environment specific property files can then choose to override the default properties if required. This approach is much simpler (no profiles, no filtering, single artefact) than the initial approach and easier to maintain. For additional deployment environments, there is no need to modify the build process, all that is required is a customized properties file in the required location.

Thursday, 18 April 2013

Spring MVC, Jackson and Filtering JSON Serialization



The default Spring JSON configuration will show all the fields of an object during serialization. Often we would like to return a subset of an entity’s properties and hide some which are only used internally such as the id and version.  Or perhaps return different properties depending on who/what is requesting the data.

As Spring uses Jackson for JSON serialization it supports the Jackson Json annotations. Jackson provides a number of options for “narrowing” or “filtering” the properties of an entity that gets serialized.

Jackson JsonViews (requires adding @JsonView to entity classes which pollutes them)
Jackson mix-in (requires extending the entity to specify @JsonIgnoreProperties)

Jackson Filtering options

Example of using Jackson views and mixin for filtering:

This one creates a new annotation to use with JsonViews but is a little too involved for my liking as it requires changing some Spring classes.

This link provides a good demo of Jackson Views and Mixins

Within my SearchController I was returning a SearchSummary object that referenced a Collector object. However, I didn’t want to return all the Collector details within the SearchSummary as its not relevant. Shown below is all I required:

@RequestMapping("/rest/loyalty")
@Controller
public class SearchController {

    @JsonIgnoreProperties({"loyaltyId","earnings","id","version"})
    private static class CollectorIdOnlyView extends Collector {
        // Empty by design ...
    } 
      
    private final ObjectMapper objectMapper = new ObjectMapper();

    private final MappingJacksonJsonView view = new MappingJacksonJsonView();      
    
    public SearchController() {         
        objectMapper.getSerializationConfig().addMixInAnnotations(Collector.class, CollectorIdOnlyView.class);
        view.setObjectMapper(objectMapper);
          
    }
    @Autowired
    private AccountService accountService;
      
    @Autowired
    private SearchService searchService;
      
    @RequestMapping(value = "/search/{id}", method = RequestMethod.GET)
    public View getSummary(@PathVariable("id") String id, Model uiModel) {
        Collector collector = accountService.findCollectorById(id);
        if(collector == null) {
              throw new RuntimeException("Collector Not Found");
        } else {
              SearchSummary searchSummary = searchService.getSearchSummary(collector);
              uiModel.addAttribute("summary",searchSummary);
              return view;
        }
       
    }
}

For the filtering I had to create a subclass of my entity to define the properties I wanted to ignore. (CustomerIdOnlyView).
This is then used to configure the ObjectMapper and View.
The change I had to make to the getSummary method was to change the return type from SearchSummary to View, add the SearchSummary to the Model and remove the @ResponseBody annotation.

Tuesday, 22 January 2013

Spring Roo Updating two entities from one View

Following on from the last post about Spring Roo, this post looks at how to customize the views and controller to update multiple entities from a single view.

Using the web mvc add-on Spring Roo generates views with crud functionality for each entity. For a given entity, Roo will typically generate views for create, show, list and update that map to methods on the generated Spring controller. By specifying attributes to the RooWebScaffold annotation, it is possible to control which views get generated.

However, there are some situations where it may be desirable to allow updating multiple entities (parent-child) from within the same view, perhaps to provide a better user experience. For example, consider a domain model with Business and User entities having a one-to-one relationship to an Address entity (managed from the Business/User). When creating a new Business or User entity, it would provide a better user experience to allow entering all the Business or User details and Address details from a single view, rather than having to create the Address from a separate view and then select the address identifier from a drop-down list within the create Business/User view (as would be the default behaviour with Roo generation).

To achieve this behaviour, the create.jspx view can be augmented with additional fields to enter the address details. Note the use of the dot-notation to navigate to the nested property of the address object.


    <form:create id="fc_com_changesoft_samples_domain_Business" modelAttribute="business" path="/businesses" render="${empty dependencies}" z="0qN2h7loptVj50JEP4Htm9WcQ2U=">
        <field:select field="businessType" id="c_com_changesoft_samples_domain_Business_businessType" items="${businesstypes}" path="businesstypes" z="lbHfbOekwe5M/bFdLTQsGY43NTs="/>
        <field:input field="businessName" id="c_com_changesoft_samples_domain_Business_businessName" z="H/Qzpi7gDgY45Ag3tLqLZiYL9wY="/>
        <field:input field="registrationNumber" id="c_com_changesoft_samples_domain_Business_registrationNumber" z="v0EWCe/zpM89BvaLz1O6+1p1ZEs="/>
        <field:input field="businessDescription" id="c_com_changesoft_samples_domain_Business_description" z="oly643Jm218C3sMXDHNnxbCaKC8="/>
        <field:input field="address.addressLine" id="c_com_changesoft_samples_domain_Address_addressLine" z="nDT/wm1FdsgfzEXLv9zJkmZybmg="/>
        <field:select field="address.addressType" id="c_com_changesoft_samples_domain_Address_addressType" items="${addresstypes}" path="addresstypes" z="aYI9UiQIlRB+F0Bwu93/eo4ZFAc="/>
        <field:input field="address.city" id="c_com_changesoft_samples_domain_Address_city" z="FVwmWn28G7JtqIfUIvAdZORMVkM="/>
        <field:input field="address.postcode" id="c_com_changesoft_samples_domain_Address_postcode" z="eezB9GBw9FiIb+ISiJosM7zXbi4="/>
    </form:create>


This results in the following rendered jsp view.

When the form is submitted, it correctly persists a new Business with a new Address entity (due to the address attribute of Business having cascading behaviour).

The update.jspx view requires slightly more work. When the update form of an entity is submitted, the id and version attributes are also present as hidden form fields and sent as request parameters to identify and retrieve the detached entity and update it. Therefore when updating 2 entities from a single view, it is also necessary to encapsulate the id and version attributes of the Address entity as hidden form fields; and subsequently submit them along with the Business attributes. The jsp tags that are provided by the web mvc add-on do not cater for hidden form fields. Therefore to fulfil this requirement it was necessary to create a custom tag that would generate an html hidden form field that could then be used within the update view jsp.


  <c:set value="hidden" var="type" />


  <c:choose>
    <c:when test="${disableFormBinding}">
      <input id="_${sec_field}_id" name="${sec_field}" type="${fn:escapeXml(type)}" />
    </c:when>
    <c:otherwise>
      <form:hidden id="_${sec_field}_id" path="${sec_field}" />
      <br />
      <form:errors cssClass="errors" id="_${sec_field}_error_id" path="${sec_field}" />
    </c:otherwise>
  </c:choose>



With the new hidden.tagx custom tag file, the update view for the Business entity is adjusted to mark any required fields as hidden:


    <field:hidden field="address.id" id="c_com_changesoft_samples_domain_Address_Id" z="user-managed"/>
    <field:hidden field="address.version" id="c_com_changesoft_samples_domain_Address_Version" z="user-managed"/>


Using the new hidden field tags, the update view renders as follows:

This view allows updating both the Business and Address entities by correctly sending the id and version properties for each entity as hidden form fields, shown below in the HTML source.

<div style="display: none;" id="_c_com_changesoft_samples_domain_Address_Id_id">
<input id="_address.id_id" name="address.id" type="hidden" value="1"/>
<br />
</div>
<div style="display: none;" id="_c_com_changesoft_samples_domain_Address_Version_id">
<input id="_address.version_id" name="address.version" type="hidden" value="2"/>
<br />
</div>
<div id="_c_com_changesoft_samples_domain_Address_addressLine_id">
<label for="_address.addressLine_id">
Address Line
:
</label>
<input id="_address.addressLine_id" name="address.addressLine" type="text" value="119 Middlesex Street"/>

This works quite well without requiring any custom code within the controller.

Spring Roo MVC Read-Only Inputs

I've recently been using Spring Roo quite regularly and also recommended it as part of the development tool stack at a client to boost productivity. It provides a lot of nice features and generates a lot of boiler-plate code for CRUD functionality. Obviously it has its limitations and when you start trying to do things differently then Roo will start having problems. Nevertheless, as long as you are willing to accept the limitations and customize where necessary, you can use it to your benefit.

Recently, I came across an issue where I wanted to update an entity from the web UI, but have some fields marked as readonly so that the user cannot modify them from the update view. Unfortunately, the custom jsp tags that the Spring Roo web mvc add-on provides doesn't support readonly input fields. The input.tagx provides a number of attributes such as render, disableFormBinding and disabled but none of these fulfilled the requirement. Using the disabled attribute, marks the input field as disabled which renders fine and doesn't allow editing of the field, but it also doesn't get submitted with the form and consequently the entity's validation fails or the field's value is replaced by an empty value.

The solution I found was to create a new inputreadonly tag by copying and customizing the input.tagx file.

I added a new jsp directive:

<jsp:directive.attribute name="readonly" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Specify if this field should be readonly" />

and modified the body where it generates the input field:

<c:otherwise>
<c:choose>
<c:when test="${readonly eq true}">
<form:input disabled="${disabled}" id="_${sec_field}_id" path="${sec_field}" readonly="${readonly}"></form:input></c:when>
<c:otherwise>
<form:input disabled="${disabled}" id="_${sec_field}_id" path="${sec_field}



Then I modified the update.jspx file to use the new jsp tag.

<field:inputreadonly field="businessType" id="c_com_changesoft_samples_domain_Business_businessType" z="user-managed>" readonly="true"/>


The result is an html read-only input field.

Friday, 5 October 2012

Container Based Authentication with Spring Security

There are occasions where applications may be required to delegate authentication to a central identity access manager or Single Sign On (SSO) provider. This post describes how an application can use Spring Security for authorization but also delegate authentication to the application server.

These scenarios are referred to as "pre-authenticated" as the user has been reliably authenticated prior to accessing the application. Spring Security provides a number of classes to support pre-authentication such as the PreAuthenticatedAuthenticationProvider class. This post demonstrates how to convert a web application based on Spring Security authentication to one that uses Container based authentication.


    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref='preAuthenticatedAuthenticationProvider'/>
    </sec:authentication-manager>

    <bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
    </bean>

    <bean id="preAuthenticatedUserDetailsService"
            class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService"/>



As Spring Security will no longer be authenticating the user, we need to modify our login page to target the standard j_security_check URI instead of the Spring j_spring_security_check.
We also need to specify the security constraints within the web.xml such as form-based login and the security role names.

Note that although we will be using Spring Security for specifying our access control rules, we still need to specify some access control within the web.xml so that the JEE container knows when to request authentication from the user.


    <filter>
        <!-- <filter-name>springSecurityFilterChain</filter-name> -->
        <filter-name>filterChainProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <!-- <filter-name>springSecurityFilterChain</filter-name> -->
        <filter-name>filterChainProxy</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

       <!-- for container based authentication -->       
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>file</realm-name>
       <form-login-config>
              <form-login-page>/login</form-login-page>
              <form-error-page>/login</form-error-page>
       </form-login-config>       
    </login-config>

    <security-role>
        <role-name>ROLE_CONSUMER_SUPPORT</role-name>
    </security-role>
    <security-role>
        <role-name>ROLE_CONSUMER_SUPPORT_READ_ONLY</role-name>
    </security-role>
    
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>All areas</web-resource-name>
            <url-pattern>/users/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ROLE_CONSUMER_SUPPORT_READ_ONLY</role-name>
            <role-name>ROLE_CONSUMER_SUPPORT</role-name>
        </auth-constraint>
    </security-constraint>
 

We have also replaced the springSecurityFilterChain bean with the filterChainProxy bean.This allows specifying (via the Spring context file) which Spring bean filters will be involved in the security process.

Note
See the source code of Spring Security Config's HttpSecurityBeanDefinitionParser#registerFilterChainProxyIfNecessary method to understand how springSecurityFilterChain is used as the default bean id for the FilterChainProxy when using the http security namespace.

So which filters are required to configure the FilterChainProxy for this container based pre-authenticated scenario?
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">

    <sec:filter-chain-map path-type="ant">
        <sec:filter-chain pattern="/**" filters="sif,j2eePreAuthFilter,logoutFilter,etf,fsi"/>
    </sec:filter-chain-map>
</bean>
The above shows five filters that have been specified in the Spring Security pre-auth sample. Lets see what each one is responsible for.


<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

<bean id="j2eePreAuthFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationDetailsSource">
            <bean class="org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource">
                <property name="mappableRolesRetriever">
                    <bean class="org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever" />
                </property>
                <property name="userRoles2GrantedAuthoritiesMapper">
                    <bean class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
                        <property name="convertAttributeToUpperCase" value="true"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
The SecurityContextPersistenceFilter is responsible for populating the SecurityContextHolder and is required to be the first filter to execute.
The J2eePreAuthFilter is what retrieves the JEE user principle name and associated roles for the pre-authenticated principle. As the container has performed the authentication, the user principle is available with associated roles and these are mapped to Spring's GrantedAuthority instances.

<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">

    <constructor-arg value="/"/>
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
</bean>
The LogoutFilter will invoke the configured list of LogoutHandler implementations and then direct the user to the url specified in the first argument. It is also possible to provide a LogoutSuccessHandler to implement any custom logic after a successful logout. The LogoutHandler's are responsible for implementing the actual logout behaviour such as invalidating the session.

<bean id="preAuthenticatedProcessingFilterEntryPoint"            class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>


<bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
    <property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/>
</bean>
The ExceptionTranslationFilter is responsible for handling any AccessDeniedException and AuthenticationException's thrown within the filter chain and mapping them to HTTP responses. It will delegate to the authenticationEntryPoint on an AuthenticationException. In the pre-authenticated scenario, the authenticationEntryPoint will simply return the HTTP error code 403 rather than commence the re-authentication process.

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>


<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="allowIfAllAbstainDecisions" value="false"/>
    <property name="decisionVoters">
        <list>
            <ref bean="roleVoter"/>
        </list>
    </property>
</bean>

<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
    <property name="securityMetadataSource">
        <sec:filter-invocation-definition-source>
            <sec:intercept-url pattern="/secure/extreme/**" access="ROLE_SUPERVISOR"/>
            <sec:intercept-url pattern="/secure/**" access="ROLE_USER"/>
            <sec:intercept-url pattern="/**" access="ROLE_USER"/>
        </sec:filter-invocation-definition-source>
    </property>
</bean>
The final filter in the chain is the FilterSecurityInterceptor that implements the access control rules for HTTP resources similar to the ones defined in the HTTP security namespace. The FilterSecurityInterceptor will first check if authentication is required, and then ask the accessDecisionManager to decide whether to grant access to a request resource. The AccessDecisionManager collaborates with the configured list of AccessDecisionVoters to resolve the authorization request.

These filters and some changes to the web.xml and login, logout forms enable transitioning a web application based on Spring Security authentication to one that uses container based authentication.

Finally, depending on the application server used, there will be some configuration required for mapping the JEE security roles.
<?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>

       <context-root>preauth</context-root>
       <security-role-mapping>
              <role-name>ROLE_USER</role-name>
              <group-name>users</group-name>
       </security-role-mapping>
       <security-role-mapping>
              <role-name>ROLE_SUPERVISOR</role-name>
              <group-name>managers</group-name>
       </security-role-mapping>  
</glassfish-web-app>

glassfish-web.xml