Engineering Full Stack Apps with Java and JavaScript
Authorization is the process of checking if a user is allowed to access a particular resource on the server. To identify the user, we need to first do authentication and hence authentication is the first step towards authorization.
Authorization may be done in different ways, including:
Programmatically controlling access to resources based on individual user’s credentials.
Assigning users into different groups called roles and assigning permissions based on the roles
Steps for role based authorization can be summarized as:
Define roles, users and create mapping between them
Define resource collections to which security should be applied
Map roles with security constraints
We can specify the roles we want to use in the application in the <role-name> element inside the <security-role> element, which is inside the <web-app> element.
You may have only one <role-name> element inside the <security-role> element, but you may have any number of <security-role> elements.
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>manager</role-name>
</security-role>
We can also declare roles using annotations over any component that implement the Servlet interface. We can use the @DeclareRoles annotation that may take one or more user roles.
Example syntax for specifying multiple roles:
@DeclareRoles({“admin”, “manager”})
Example syntax for specifying a single role:
@DeclareRoles({“admin”})
Or
@DeclareRoles(“admin”)
Assigning users to roles are specific to Java EE servers. It may be done in many different ways, including:
Using a dedicated file stored in the Java EE server environment
Using a local or remote database to store a list of user credentials and roles
Querying a directory service such a LDAP
Using the user credentials and user groups native to the operating system on which the Java EE server is running
Glassfish server, for example, allow using keyfile realm (usernames and hashed (digest) passwords stored on files), retrieval using LDAP, JDBC realm (looking credentials from a database) and certificate realm (authenticates clients using their SSL certificates).
Apache Tomcat server, by default, support XML configuration files to store user and role mappings and also JDBC realm (looking credentials from a database).
After defining users and roles, we need to define what web resources you need to restrict access to.
Authorization and confidentiality requirements for a specified collection of web resources can be specified using the <security-constraint> sub element of the <web-app> element. If different security requirements are required for different set of web resources, separate <security-constraint> elements need to be configured for each of those sets.
<web-app>
…
<security-constraint>
<display-name> Security Constraint 1</display-name>
</security-constraint>
…
</web-app>
Web resource elements can be specified using the <web-resource-collection> sub element of <security-constraint> element.
Sub elements of <web-resource-collection> include:
<web-resource-name>
Specifies the logical name given to this collection
One per collection
<url-pattern>
Pattern to which every incoming request will be matched for applying this security constraint.
One or more (one per pattern)
<http-method>
Specify each HTTP method which should fall under this security constraint.
Optional (one per HTTP method)
If not specified, it will match all HTTP methods that match the url pattern.
Same resource may be declared in more than one <security-constraint> element, and container will combine all those together for accessing that resource.
We have defined users and roles, and also defined security constraints. We can map security constraints with user roles using the <auth-constraint> sub element of <security-constraint> element. We can use the <role-name> sub element of <auth-constraint> element for every role you want to apply this constraint.
<auth-constraint>
<role-name>admin</role-name>
<role-name>manager</role-name>
…
</auth-constraint>
Important Note!
A declaration of the form <role-name>*</role-name> denote all authenticated users belonging to all roles in the application. Any additional <role-name> declarations will be thus redundant.
Omitting all <role-name> elements will grant access to all users irrespective of whether they are authenticated or not.
Same resource may be declared in more than one <security-constraint> element, and container will combine all those together (including allowed roles) for accessing that resource.