Search code examples
jakarta-eeglassfishweldpayara

Glassfish (Payara) REST error. Postman request fails with 403/401 with custom token filter


I have Payara version 182 and have a custom token validation.

@Priority(Priorities.AUTHENTICATION)
public class TokenAuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) {
    // put user into security context so it is available later for role 
     based security and application usage
     requestContext.setSecurityContext(new UserSecurityContext(currentUser, 
    requestContext.getUriInfo().getRequestUri().getScheme()));
    }
}

glassfish-web.xml :

<glassfish-web-app error-url="">
  <security-constraint>
      <web-resource-collection>
          <web-resource-name>Protected Area</web-resource-name>
          <url-pattern>/jsp/security/protected/ *</url-pattern>
          <http-method>PUT</http-method>
          <http-method>DELETE</http-method>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint>
          <role-name>manager</role-name>
      </auth-constraint>
    <security-role-mapping>      
      <role-name>SystemAdmin</role-name>
      <principal-name>SystemAdmin</principal-name>
      <group-name>SystemAdmin</group-name>
    </security-role-mapping>
    <security-role-mapping>
      <role-name>ADMIN</role-name>
      <principal-name>ADMIN</principal-name>
      <group-name>ADMIN</group-name>
    </security-role-mapping>
    <security-role-mapping>
      <role-name>UserRole</role-name>
      <principal-name>user</principal-name>
      <group-name>appuser</group-name>
    </security-role-mapping>
    <security-role-mapping>
      <role-name>rest-monitoring</role-name>
      <group-name>rest-monitoring</group-name>
    </security-role-mapping>
  </security-constraint>
</glassfish-web-app>

The problem is when I perform a request in Postman I receive a 403 Forbidden. I tried playing around with roles in glassfish-web.xml and then I receive a 401 and get redirected to a page but this happens AFTER I am successfully able to call the method in the controller. I get this 401 even though I am able to successfully call the method.


Solution

  • If you want to specify the roles in web.xml, you have to authenticate the user before the JAX-RS servlet is called. Authenticating in the JAX-RS filter is too late.

    You could authenticate with the new Security API using the HttpAuthenticationMechanism as described in this article: https://www.ibm.com/developerworks/library/j-javaee8-security-api-2/index.html#ibm-h2

    The problem is that you define security at a higher level compared to the level at which you authenticate the user. Roles defined in the web.xml are applied sooner than the JAX-RS filter, before the user is authenticated and you get 403. The reason is that the JAX-RS is implemented as a servlet and Payara needs to first run the servlet, which runs the JAX-RS engine, which runs your filter. But the configuration in web.xml denies access to the servlet even before JAX-RS engine and your filter is executed.

    On the other hand, a HttpAuthenticationMechanism is detected by Payara Server and executed before security checks from web.xml are applied.