Authorization

For an application to be secure, it must manage access to protected resources. Authorization determines which resources a user can access.

In applications where only certain users are entitled to access certain resources, users and groups are assigned roles that correspond to the resources that they can access. Authorization determines a user’s role and the permissions that role includes. For example, in a payroll application, users in the Employee role can view a page that lists their hourly wages and hours worked. However, only users in the Manager role can edit employee wages. During authentication, Open Liberty identifies users and determines what access groups they belong to. When a user attempts to access a protected resource on the server, this information determines whether the user is authorized to access the resource.

Define roles in your application

You can specify which roles can access an application resource by setting the @RolesAllowed annotation on a class or method in the source code, as shown in the following example:

@RolesAllowed({ "admin", "user" })

You can map the roles that are declared in the application to existing groups from a user registry or SSO identity provider. To map the roles, you can specify the security-role element within the application-bnd element in the server.xml file, as shown in the following example:

<application-bnd>
   <security-role name="admin">
     <group name="Manager" />
     <group name="TeamLead" />
   </security-role>
   <security-role name="user">
     <group name="Employee" />
   </security-role>
</application-bnd>

The name attribute of the security-role element corresponds to a role that is specified in the application to control access to resources. The name attributes of the group elements correspond to the groups that are specified by a user registry or SSO identity provider. If the role names match the group names exactly, the server maps the group to the role with a matching name by default. If you use this default mapping, you do not need to specify an application-bnd element in the server.xml file.

In some cases, an application needs to know only the user’s authentication status. In such cases, you can specify the ** value as the role name in the @RolesAllowed annotation. This value denotes that any authenticated user can access a resource. You can also authorize all users by setting the @PermitAll annotation on a class or method in the application code The @PermitAll annotation specifies that anyone can access a resource, even users who are not authenticated.

Open Liberty provides a dropins directory, which is automatically monitored by the server. If you put an application into this directory, the application is automatically deployed on the server. Similarly, if the application is deleted from the directory, the application is automatically removed from the server. The dropins directory can be used for applications that do not require security role mapping or other extra configuration in the server.xml file. However, if you specify the application-bnd element in your server.xml file to configure security role mapping, your application must not be in the dropins directory. If you leave your application in the dropins directory, then you must disable application monitoring by adding the following code in your server.xml file:

<applicationMonitor dropinsEnabled="false" />

Configure servlet security roles

The @RolesAllowed annotation typically specifies role-based access to back-end application resources, such as calls to a database. To control authorization for front-end resources, such as HTTP calls, you can specify roles by configuring the @ServletSecurity annotation on a class in the servlet code. You can specify the permissible roles with the rolesAllowed attribute on the @HttpConstraint or @HttpMethodConstraint parameters. The @HttpMethodConstraint parameter specifies constraints for specific HTTP methods. The @HttpConstraint parameter specifies the default constraints for all HTTP methods that are not otherwise specified by the @HttpMethodConstraint parameter.

In the following example, the @HttpConstraint parameter specifies that all HTTP methods are constrained either to the user role or the admin role. The @HttpMethodConstraint parameter specifies that the POST method is constrained only to users who are in the admin role:

@ServletSecurity (value = @HttpConstraint(rolesAllowed = { "user", "admin" }),
  httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"admin"})})

Authorize requests between web services

Authorization occurs not only between users and applications, but also between microservices within an application. When one service requests data from another, the requesting service often must demonstrate that it is authorized to access the data. Token-based authorization, such as with a JSON Web Token (JWT), provides a lightweight way for security controls and security tokens to propagate user identities and roles across different services.

Open Liberty supports token-based authorization through the MicroProfile JWT feature.

Configure authorization with a deployment descriptor file

Although annotations are the most common way to define roles in microservices, you can also define roles by specifying security-constraint elements in a web.xml deployment descriptor file. This configuration might be necessary in situations where you want to keep the security configuration separate from the development environment and apply it at deployment time.

Some applications rely on a combination of declarative annotations and a deployment descriptor file. In these cases, deployment descriptor values supersede annotations. Therefore, you can specify roles in a deployment descriptor file if you want to override security settings or defaults from elsewhere in the application code. For more information, see the Adding authentication and authorization section of the Securing a web application guide.

Configure calls to run under a specific caller identity

When a user is authenticated to a servlet, the servlet can make subsequent calls to downstream resources, such as other servlets or EJB components. These subsequent calls are normally made under the same security identity that was used to log in to the servlet. This identity is known as the caller identity. Alternatively, you can delegate any subsequent calls to a different caller identity.

To delegate calls to a specific caller identity, you must either specify the @RunAs annotation on a class in your application code or add the run-as element to your deployment descriptor file. In either case, you must set the annotation or element to the security role that you want to delegate to. You must also specify the run-as element on that security role in your server configuration to map it to a particular user ID.

For example, consider a servlet that requires either the admin or user role to authenticate. You can delegate subsequent calls from that servlet to the admin role by specifying the @RunAs annotation in your application code, as shown in the following example:

@RunAs("admin")
@RolesAllowed({ "admin", "user" })

For more information, see the @RunAs annotation.

Alternatively, in the following web.xml deployment descriptor file example, the run-as element specifies that the servlet makes calls under the admin role that is defined in the server configuration:

<servlet id="Servlet_1">
     <servlet-name>RunAsServlet</servlet-name>
     <display-name>RunAsServlet</display-name>
     <description>RunAsServlet</description>
     <servlet-class>web.RunAsServlet</servlet-class>
     <run-as>
          <role-name>admin</role-name>
     </run-as>
 </servlet>

To delegate calls that are made from a security role to a particular caller identity, specify the run-as element in the security role configuration in your server.xml file. For example, the servlet from the previous example needs to call to downstream resources that require a particular caller identity with the username Wanda. You can set the run-as element on the admin security role to specify that calls that are made in that role must use this caller identity.

In the following server.xml file example, the run-as element specifies that calls under the admin security role are run under the caller identity with the Wanda username :

<application-bnd>
      <security-role name="admin">
           <user name="Wanda" />
           <user name="Trevor" />
           <run-as userid="Wanda" />
       </security-role>
 </application-bnd>

If you configure the run-as element on a security role in your server.xml file, providing a password is optional. However, if this configuration is specified in an ibm-application-bnd.xml file, the password is required.