12. Web application security



Worthwhile reading:



12.1 Understand the role of the container in security

Four concepts:

  • Authentication: The means by which communicating entities prove to one another that they are acting on behalf of specific identities that are authorized for access.
  • Authorization: Access control for resources: The means by which interactions with resources are limited to collections of users or programs for the purpose of enforcing integrity, confidentiality, or availability constraints.
  • Confidentiality or Data Privacy: The means used to ensure that information is made available only to users who are authorized to access it.
  • Data Integrity: The means used to prove that information has not been modified by a third party while in transit

The container checks the URL accessed and login credentials (username, password) against an internal table (username, password, role) and may send a '401 Unauthorized' error page. Other relevant codes are '403 Forbidden' for resources that no user has access to.

Authentication is performed prior to authorization. Security should ideally be done declaratively.

A realm (<realm-name>) is a place where authentication information is stored. It is valid only for Basic, Digest and Form authentication.

Authorization Step 1: defining roles

tomcat-users.xml (e.g. C:\xampp\tomcat\conf\tomcat-users.xml)

<tomcat-users>
    <role rolename="Admin"/>
    <role rolename="Member"/>
    <role rolename="Guest"/>
    <user username="Annie" password="admin" roles="Admin, Member, Guest" />
    <user username="Diane" password="coder" roles="Member, Guest" />
    <user username="Ted" password="newbie" roles="Guest" />
</tomcat-users>

web.xml

    <security-role>
        <role-name>Admin</role-name>
    </security-role>
    <security-role>
        <role-name>Member</role-name>
    </security-role>
    <security-role>
        <role-name>Guest</role-name>
    </security-role>

Authorization Step 2: defining resource/method constraints

  • 1 or more <web-resource-collection>
  • 0 or 1 <auth-constraint>
  • 0 or 1 <user-data-constraint>

web.xml:

<security-constraint> <!-- can have many of these elements -->
    <web-resource-collection> <!-- can have many of these elements -->
            <web-resource-name>secure</web-resource-name> <!--optional name used by tools -->
            <url-pattern>/security/admin_and_member1.jsp</url-pattern> <!-- resources to be constrained -->
            <url-pattern>/security/*</url-pattern>
        <http-method>GET</http-method> <!-- restricted methods. if none specified, all are constrained -->
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint> <!-- if absent, the Container MUST allow unauthenticated access for these URLs -->
        <role-name>Admin</role-name>  <!-- optional allowed roles. Applies to all web-resource-collection elements -->
        <role-name>Member</role-name>
    </auth-constraint>
</security-constraint>
  • <http-method-omission> is opposite of <http-method> and new in 3.0. http-method-omission and http-method elements are never mixed in the same collection

<role-name> rules

  • Within an <auth-constraint> element, the <role-name> element is OPTIONAL.
  • If <role-name> elements exist, they tell the Container which roles are ALLOWED.
  • If an <auth-constraint> element exists with NO <role-name> element, then NO USERS ARE ALLOWED.
  • If <role-name>*</role-name> then ALL users are ALLOWED.
  • Role names are case-sensitive

<auth-constraint> rules

  • Within a <security-constraint> element, the <auth-constraint> element is OPTIONAL.
  • If an <auth-constraint> exists, the Container MUST perform authentication for the associated URLs.
  • If an <auth-constraint> does NOT exist, the Container MUST allow unauthenticated access for these URLs. Same as: <role-name>*</role-name>
  • For readability, you can add a <description> inside <auth-constraint>
  • NO <auth-constraint> (allow all) is the opposite of an EMPTY <auth-constraint/> (allow none)

multiple <security-constraint> rules

  • When combining individual role names, all of the role names listed will be allowed.
  • A role name of " * " combines with anything else to allow access to everybody.
  • An empty <auth-constraint> tag combines with anything else to allow access to nobody! In other words, an empty <auth-constraint> is always the final word!
  • If one of the <security-constraint> elements has no <auth-constraint> element, it combines with anything else to allow access to everybody

Programmatic security

After user is authenticated, isUserInRole() is called with a role argument. Returns true or false. .e.g

if( request.isUserInRole("Manager")) {

in web.xml, <security-role-ref> can be used to lookup a <security-role>. e.g.

<servlet>
    <security-role-ref>
        <role-name>Manager</role-name>
            <role-link>Admin</role-link>
    </security-role-ref>
</servlet>
 
<security-role>
    <role-name>Admin</role-name>
</security-role>

Programmatic methods are:

  • getRemoteUser, which determines the user name with which the client authenticated. The getRemoteUser method returns the name of the remote user (the caller) associated by the container with the request. If no user has been authenticated, this method returns null.
  • isUserInRole, which determines whether a remote user is in a specific security role. If no user has been authenticated, this method returns false. This method expects a String user role-name parameter.
  • getUserPrincipal, which determines the principal name of the current user and returns a java.security.Principal object. If no user has been authenticated, this method returns null. Calling the getName method on the Principal returned by getUserPrincipal returns the name of the remote user.

Servlet 3.0

Servlet 3.0 specifies the following methods of the HttpServletRequest interface that enable you to authenticate users for a web application programmatically:

boolean authenticate(HttpServletResponse response)
Use the container login mechanism configured for the ServletContext to authenticate the user making this request. If you call this method, the container will send such a response that will cause the browser to prompt the user to enter his/her user name and password.

void login(username, password)
You call this method when you get the username and password from the user. ServletException - if the configured login mechanism does not support username password authentication, or if a non-null caller identity had already been established (prior to the call to login), or if validation of the provided username and password fails.

void logout()
Once you call this method, getUserPrincipal, getRemoteUser, and getAuthType methods return null.



12.2 Describe and implement four authentication models

  1. BASIC
  2. DIGEST (not required in JEE 6)
  3. CLIENT-CERT
  4. FORM

BASIC and DIGEST are based on built-in mechanism of HTTP.

Type Spec Data Integrity Comments
BASIC HTTP Base64 - weak HTTP standard, all browsers support it
DIGEST HTTP Stronger - but not SSL Optional for HTTP and J2EE containers
FORM J2EE Very weak, no encryption Allows a custom login screen
CLIENT-CERT J2EE Strong - public key, (PKC) Strong, but users must have certifcates

<realm-name> is optional and depends on the container vendor

BASIC

Transmits the login information in a base64 encoded (not encrypted) form.

<login-config>
    <auth-method>BASIC</auth-method>
</login-config>

DIGEST

Transmits the login information in a more secure way, not widely used.

<login-config>
    <auth-method>DIGEST</auth-method>
</login-config>

CLIENT-CERT

Transmits the login information in an extremely secure form, using Public Key Certificates (PKC). Used for B2B.

The CLIENT-CERT authentication method is typically used for identifying the user by his X.509 certificate. This is a special usage of the Secure Sockets Layer (SSL) where both the server and the user are identified by their own certificates. Thus, this mechanism requires the client to possess a Public Key Certificate (PKC).

<login-config>
    <auth-method>CLIENT-CERT</auth-method>
</login-config>

FORM

Using login form, least secure as no encryption is used when sending username and password.

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/loginPage.html</form-login-page>
        <form-error-page>/loginError.html</form-error-page>
    </form-login-config>
</login-config>

loginPage.html

<form method="POST" action="j_security_check">
    <input type="text" name="j_username">
    <input type="password" name="j_password">
    <input type="submit" value="Enter">
</form>

loginError.html

<html>
<body>
    wrong password
</body>
</html>



12.3 Force the use of encryption between a web application and the client browser

The container may send a 301 Redirect if a user tries to access a resource over HTTP, rather than HTTPS. The browser will then use a secure connection. This check will occur prior to authentication. Every resource that requires being logged-in should have a transport-guarantee.

Options for <transport-guarantee> within <user-data-constraint>

  • NONE - This is the default, no data protection
  • INTEGRAL - The data must not be changed along the way, usually using SSL
  • CONFIDENTIAL - The data must not be seen by anybody along the way, using SSL
  • In practice, Java EE servers treat the CONFIDENTIAL and INTEGRAL transport guarantee values identically.
<security-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>



12.4 Understand the role of JAAS in pluggable/extensible authentication for web applications



Annotations for Security

This section collect information on @ServletSecurity, @HttpConstraint and @HttpMethodConstraint . Any values explicitly specified in the deployment descriptor override any values specified in annotations.

You use the @HttpConstraint and, optionally, the @HttpMethodConstraint annotations within the @ServletSecurity annotation to specify a security constraint.

@HttpConstraint and @HttpMethodConstraint annotations accept a rolesAllowed element that specifies the authorized roles.

Examples:

@WebServlet("/SecureServlet")
@ServletSecurity(value = @HttpConstraint(rolesAllowed = "member"),
        httpMethodConstraints = {
            @HttpMethodConstraint(value = "GET", rolesAllowed = "member"),
            @HttpMethodConstraint(value = "POST", rolesAllowed = "admin",
            transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL),
        })
public class ServletAnnotatedSecurity extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 
                                      throws ServletException, IOException {
        PrintWriter out = httpServletResponse.getWriter();
        out.println("secure servlet");
    }
}

@ServletSecurity

This annotation takes two parameters (both are optional):

  1. value: The HttpConstraint that defines the protection to be applied to all HTTP methods that are NOT represented in the array returned by httpMethodConstraints. Default value is empty HttpConstraint.
  2. httpMethodConstraints:  the array of HTTP method specific constraints.
Name Type Required Description
httpMethodConstraints HttpMethodConstraint[] Optional Specifies HTTP method constraints which will apply for the servlet.
value HttpConstraint Optional Specifies a constraint that applies to all HTTP methods that are not specified by the httpMethodConstraints.

@HttpConstraint

The @HttpConstraint annotation is used within the @ServletSecurity annotation to represent the security constraint to be applied to all HTTP protocol methods for which a corresponding @HttpMethodConstraint does NOT occur within the @ServletSecurity annotation.

It takes three arguments (all are optional):

  1. value:  The default authorization semantic that applies (only) when rolesAllowed returns an-empty array. Default is PERMIT
  2. rolesAllowed : An array containing the names of the authorized roles. Default is empty string array. Note: * has no special meaning
  3. transportGuarantee : The data protection requirements that must be satisfied by the connections on which requests arrive. Default is NONE. Note: While transport-guarantee element in DD has three valid values (NONE, CONFIDENTIAL, and INTEGRAL), the ServletSecurity.TransportGuarantee enum has only two, namely CONFIDENTIAL and NONE.
Name Type Required Description
rolesAllowed String[] Optional Specify authorized role names.
transportGuarantee ServletSecurity.TransportGurantee Optional Specifies type of data protection that applies for the connection (SSL/TLS).
value ServletSecurity.EmptyRoleSemantic Optional Specifies the default authorization semantic when no roles specified by the array rolesAllowed.

@HttpMethodConstraint

The @HttpMethodConstraint annotation is used within the @ServletSecurity annotation to represent security constraints on specific HTTP protocol messages. It accepts four parameters:

  1. value (This is required): The HTTP protocol method name
  2. emptyRoleSemantic : The default authorization semantic that applies (only) when rolesAllowed returns an empty array. Default is PERMIT
  3. rolesAllowed : An array containing the names of the authorized roles. Default is {}
  4. transportGuarantee : The data protection requirements that must be satisfied by the connections on which requests arrive. Default is NONE
Name Type Required Description
value String Required Name of HTTP method.
emptyRoleSemantic ServletSecurity.EmptyRoleSemantic Optional Specifies the default authorization semantic that applies for the servlet when no roles specified by the array rolesAllowed.
rolesAllowed String[] Optional Specifies role names that are authorized to access the servlet.
transportGuarantee ServletSecurity.TransportGurantee Optional Specifies type of data protection that applies for the connection (SSL/TLS).

emptyRoleSemantic

The authorization semantic, either PERMIT or DENY, that applies when no roles are named in rolesAllowed. The default value for this element is PERMIT, and DENY is not supported in combination with a non-empty rolesAllowed list.

This parameter is used in both HttpConstraint and HttpMethodConstraint annotations.

@ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))  
// This means: for all HTTP methods, all access is denied.   
 
@ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),    
                            httpMethodConstraints = @HttpMethodConstraint(value="TRACE", emptyRoleSemantic = EmptyRoleSemantic.DENY)  
/* This means for all HTTP methods except TRACE, auth-constraint requires membership in Role R1; 
for TRACE, all access is denied. */

Examples

The following are some examples from Servlet 3.0 Specification. You should try to understand these because there are questions in the exam in similar pattern.

@ServletSecurity
/* This implies all users are permitted to access all HTTP methods because the value of value parameter is an empty 
HttpConstraint, which permits all to access all HTTP methods.    */
 
@ServletSecurity(@HttpConstraint(transportGuarantee =TransportGuarantee.CONFIDENTIAL))
// For all HTTP methods, no auth-constraint, confidential transport required 
 
@ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))
// For all HTTP methods, all access denied  
 
@ServletSecurity(@HttpConstraint(rolesAllowed = "R1"))
// For all HTTP methods, auth-constraint requiring membership in Role R1  
 
@ServletSecurity((httpMethodConstraints = { @HttpMethodConstraint(value = "GET", rolesAllowed = "R1"),
                    @HttpMethodConstraint(value = "POST", rolesAllowed = "R1",
                    transportGuarantee = TransportGuarantee.CONFIDENTIAL) })
/* For All HTTP methods except GET and POST, no constraints; for methods GET and POST, auth-constraint requiring 
membership in Role R1; for POST, confidential transport required  */
 
@ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"), 
                httpMethodConstraints = @HttpMethodConstraint("GET"))
// For all HTTP methods except GET auth-constraint requiring membership in Role R1; for GET, no constraints  
 
@ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"), 
                httpMethodConstraints = @HttpMethodConstraint(value="TRACE",             
                emptyRoleSemantic = EmptyRoleSemantic.DENY))
// For all HTTP methods except TRACE, auth-constraint requiring membership in Role R1; for TRACE, all access denied

@DeclareRoles

The following are equivalent:

Annotation:

import javax.annotation.security.*;
import javax.servlet.http.*;
import java.io.*;
 
@DeclareRoles("Barbra")
public class MyBarbra extends HttpServlet {
}

web.xml:

<web-app ...>
    <security-role>
         <role-name>Barbra</role-name>
    </security-role>
</web-app>

The syntax for declaring more than one role is as shown in the following example:

@DeclareRoles({"Administrator", "Manager", "Employee"})






Comments

If you have questions, corrections, information or examples to add, please comment below.

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License