Servlet security dynamic annotations

When you use the programmatic APIs to add or to create a servlet, the security annotations, RunAs, declareRoles and ServletSecurity, can be dynamically updated through the setRunAsRole(), declareRoles() and setServletSecurity() methods respectively.

Note: Support for the dynamic updating of the RunAs, declareRoles, and ServletSecurity servlet security annotations is new in this release of WebSphere® Application Server.

When an application starts, the web container inspects all servlets with the RunAs, declareRoles, and ServletSecurity annotations, and sets those annotations on the setServletSecurity() method of the ServletRegistration annotation. The web container notifies the security component to inspect all ServletRegistration annotations that have URL patterns and security constraints. The security component then determines if a URL pattern is defined in the deployment descriptor. If an exact match is already defined in the deployment descriptor, the security constraints and RunAs role in the URL pattern of the deployment descriptor are used instead of the dynamic data.

Avoid trouble: If the dynamic security annotations, declareRoles, setRunAs and rolesAllowed, are used, the role name must be pre-defined, either through the deployment descriptor or through the declareRoles and or RunAs annotations in the servlet class. During deployment time, you can use the administrative console to map a user or group to this role.

If you have an exact URL pattern match for the ServletSecurity annotation in the security dynamic annotation, the security constraint of the URL pattern in the security dynamic annotation takes precedent. Also, if you call the setServletSecurity() method multiple times with the same URL pattern, the last one takes precedent.

  • ServletRegistration.Dynamic.setRunAsRole(String roleName) sets the name of the RunAs role for this servlet registration.
  • ServletContext.declareRoles(String roleNames) declares role names that are tested for the isUserInRole() method.
  • ServletRegistration.Dynmaic.setServletSecurity(ServletSecurityElement constraint) sets the ServletSecurityElement for this servlet registration.
Note: When the web authentication system property, com.ibm.wsspi.security.web.webAuthReq, is set to persisting, you can log into an unprotected URL if a valid username and password are provided.

The following two examples can be used to set the security constraints and RunAs role for dynamic servlets by using the setServletSecurity() method.

In this example, all HTTP elements require membership in the Employee role except for the PUT method. For the PUT method, the <auth-constraint> element requires membership in the Manager role and TransportGuarantee is confidential.
HttpConstraintElement constraint = new HttpConstraintElement(TransportGuarantee.NONE,
new String[]{"Employee"});
List<HttpMethodConstraintElement> methodConstraints =
new ArrayList<HttpMethodConstraintElement>();
methodConstraints.add(new HttpMethodConstraintElement("PUT",
new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL, new String[]{"Manager"})));
ServletSecurityElement servletSecurity =
new ServletSecurityElement(constraint, methodConstraints);
In this example, all HTTP methods are allowed except for the CUSTOM and GET methods. For the CUSTOM method, the <auth-constraint> element requires membership in the Manager role. For the GET method, the <auth-constraint> element requires membership in the Employee role, and TransportGuarantee is confidential.
HttpConstraintElement constraint = new HttpConstraintElement();
List<HttpMethodConstraintElement> methodConstraints = 
new ArrayList<HttpMethodConstraintElement>();
methodConstraints.add(new HttpMethodConstraintElement("CUSTOM", 
new HttpConstraintElement(TransportGuarantee.NONE, new String[]{"Manager"})));
methodConstraints.add(new HttpMethodConstraintElement("GET", 
new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL, new String[]{"Employee"})));
ServletSecurityElement servletSecurity = new ServletSecurityElement(constraint, 
methodConstraints);