<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2002-2004 The Apache Software Foundation or its licensors,
  as applicable.
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
  http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE document PUBLIC "-//WAMBLEE.ORG//ENTITIES Include Extension for Xdoc V1//EN"
"includeExtension-v1.dtd">
<document> 
  <header> 
    <title>Security Design</title> 
  </header> 
  <body> 
    <p>This document explains the requirements and the design of security in PhotoXChange.</p>
    
    <section>
      <title>Introduction</title>
      <p>The security framework provides the means to authenticate users and control access
      to restricted resources based on user roles. Here, the authorization rules extend beyond
      those provided by the J2EE platform. Also, it should be possible to implement security 
      aware functionality without being dependent on J2EE specific APIs. Hence a security
      framework is provided. </p>
    </section>
    <section id="requirements">
      <title>Requirements</title>
      
      <section id="authentication">
        <title>Authentication</title>
        
        <ol>
          <li>
              It shall be possible to restrict the viewing and/or modification of 
              content to autheticated users. 
          </li>
          <li>
              It shall be possible to log out of the apolication.
          </li>
          <li>
              Once a user is authenticated, the user identity shall be available in all parts of 
              the application.
          </li>
          <li>
              It shall not be possible to view or modify content that a user is not allowed to 
              by constructing certain HTTP requests. 
          </li>
          <li>
              It shall be possible for some parts of the application to be publicly accessible
              while others can only be viewed by authenticated users. 
          </li>
          <li>
            It shall be possible to integrate seamlessly with standard J2EE security. 
          </li>
          <li>
            It shall be possible to use security APIs without depending on J2EE-specific APIs. 
          </li>
        </ol>
      </section>
      
      <section id="authorization">
        <title>Authorization</title>
        <ol>
          <li>
            It shall be possible to check whether an operation on a specific resource is allowed or
            not. 
          </li>
          <li>
            Authorization shall at least support authorization based on group and resource where any user can be
            a member of one or more groups. 
          </li>
          <li>
            The authorization framework shall at least support resources identified by a path and a
            type, where one authorization rule can explicitly grant or deny access to a set of
            resources to a single group for all resources below a given path. 
          </li>
          <li>
            The authorization framework shall at least support the following operations: reading a
            resource, modifying a resource, and deleting a resource. 
          </li>
          <li>
            The authorization framework shall be extendible with new types of resources and
            operations. 
          </li>
        </ol>
      </section>
      
      <section id="integrity">
        <title>Integrity</title>
        <p>
          We assume that the application server and database environments are such 
          that information cannot be altered by third parties. 
        </p>
      </section>
      
      <section id="confidentiality">
        <title>Confidentiality</title>
        <p>
          We assume that the application server and database environments are configured 
          and secured appropriately to guarantee confidentiality. 
        </p>
      </section>
      
    </section>
    
    <section id="design">
      <title>Design</title>
      <p>
        To cover the authentication requirements the following design principles are used: 
      </p>
      <ul>
        <li>JAAS authentication is used. As a result, after authentication, the JAAS APIs can be
          used to obtain the user identity everywhere in the application without needing to pass
          information through the argument list.</li>
        <li>A servlet filter is used which filters all incoming requests to the application and
          which logs in using JAAS (and logs out after the the request is processed),
          provided user credentials are available. The user credentials are
          stored in the HTTP session.
        </li>
        <li>Form based authentication is used obtain control in how to format the 
          login page and to provide good integration with the application server environment.</li>
        <li>J2EE declarative security is used to control access to pages. Currently, with Tapestry 3, 
          no control over the URL space is possible so that currently the entire Web application requires
          an authenticated user. This restriction will be removed once we migrate to Tapestry 4 that allows
          more control over the URL space.  </li>
        <li>A <code>ProtectedPage</code>, base class is used for all pages that can only be viewed by 
          authenticated users which extends the Tapestry <code>BasePage</code> class and 
          checks whether the user is logged in. If not an error is generated.</li>
        <li>Using a tapestry component, all pages will show a logout link in case the user 
          is logged in. The logout will remove the user credentials from the session and will 
          therefore logout.</li>
      </ul>
      
    </section>
    
    <section id="structure">
      <title>Structure</title>
      
      <section id="structure-security-overview">
        <title>Package Overview</title>
        
        <p>
          The authentication packages are <code>org.wamblee.security.servlet</code> and 
          <code>org.wamblee.security.tapestry</code>. The first package contains general 
          security related functionality for use in web applications. The <code>tapestry</code>
          package contains specific security related support for the Tapestry web application.
          An authorization framework is contained in the
          <code>org.wamblee.security.authorization</code> package. Security depends on user
          management.
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.packages.jpg" 
	        alt="Package overview. " />
       
      </section>
      
      
      <section id="structure-security-servlet">
        <title>Authentication for the Web App.: Package <code>org.wamblee.servlet.security</code></title>
        
        <p>
          The <code>AuthenticationFilter</code> is a servlet filter that takes care
          of executing requests as an authenticated Subject using 
          <code>Subject.doAs()</code> when a Subject is available. The Subject is made 
          available in the application server as part of the FORM based authentication. 
          To retrieve the authenticated subject, the <code>SubjectLocator</code> is used. 
          This interface has one implementation for JBoss that retrieves the Subject from 
          the JBoss security manager. This retrieval is done using OGNL (Object Graph Navigation 
          Language) to avoid dependencies on JBoss-specific classes in the code. 
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.servlet.filter.jpg" 
	        alt="Authentication filter. "/>
     
      </section>
      
      <section id="structure-security-tapestry">
        <title>Authentication in Tapestry: Package <code>org.wamblee.servlet.tapestry</code></title>
        
        <p>
          A subclass of <code>BasePage</code> called <code>ProtectedPage</code> is provided
          that represents pages that require an authenticated used. This class implements the 
          <code>PageValidateListener</code> interface from Tapestry so that its <code>pageValidate()</code>
          method is called before the page is rendered. The <code>pageValidate()</code> method
          checks whether the user is logged in and if not throws an exception. This design is 
          possible since J2EE declarative security is used in such a way that this situation can
          only occur in case of programming and/or configuration errors. . 
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.tapestry.jpg" 
	        alt="Security in Tapestry."/>
      </section>
      
      <section>
        <title>Authorization: Resource and Operation</title>
        
        <p>
          There is no special class to represent a resource. The resource on which some operation
          is requested (or a representation of this resource) is used instead. The framework defines
          four operations for reading, writing, creation, and deletion, as well as one operation
          type which groups these four.
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.authorization.operation.jpg" 
          alt="Representation of an operation on a resource."/>
      </section>
      
      <section>
        <title>Authorization: Result of authorization</title>
        
        <p>
          The result of an authorization is defined as an enumerated type with the values:
        </p>
        <ul>
          <li><strong>GRANTED</strong>: the operation is granted.</li>
          <li><strong>DENIED</strong>: the operation is denied.</li>
          <li><strong>UNDECIDED</strong>: when an authorization rule applies to the resource type but does not
            match.</li>
          <li><strong>UNSUPPORTED_RESOURCE</strong>: When an authorization rule does not apply to
            the specified resource type.</li>
        </ul>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.authorization.result.jpg" 
          alt="Result of authorization."/>
      </section>
      
      
      <section>
        <title>Authorization: Authorization Rule</title>
        
        <p>
          The basic ingredient for the authorization framework is a single authorization rule. 
          To check whether an operation is allowed on a resource, a number of rules are consulted
          in a specified order using their <code>isAllowed()</code> method. A rule also provides an
          interface for getting the supported resource types to which it applies. In case a rule
          applies it returns <code>GRANTED</code> or <code>DENIED</code>, otherwise, it returns 
          <code>UNDECIDED</code> or <code>UNSUPPORTED_RESOURCE</code>. An authorization rule must be
          persistent. 
        </p>
        <figure
          src="../umlpictures/class-diagram-org.wamblee.security.authorization.rule.jpg"
          alt="Authorization rule."/>
        <p>
          The <code>UrlAuthorizationRule</code> is a fully parametrized abstract base class for 
          other concrete rule implementations. It is constructed with a number of rules to determine
          if a rule matches, as well as a result to return in case the rule matches. Specifically,
          for a rule to apply, the following conditions must hold: 
        </p>
        <ul>
          <li>The type of resource must be a subclass of a specified class. </li>
          <li>The user must match as specified by the <code>UserCondition</code>.</li>
          <li>The path of the resource must match as specified by the <code>PathCondition</code>.</li>
          <li>The operation on the resource must match as specified by the
            <code>OperationCondition</code>.</li>
        </ul>
        <p>
          To use the <code>UrlAuthorizationRule</code>, a subclass must be implemented which
          implements the <code>getResourcePath()</code> method to return the path for a given
          resource. 
        </p>
        <figure
          src="../umlpictures/class-diagram-org.wamblee.security.authorization.usercondition.jpg"
          alt="User condition."/>
        
        <p>Two types of user conditions are implemented: <code>AnyUserCondition</code> which matches
        any user and <code>GroupUserCondition</code> which matches in case the user is part of a
          specified group.</p>
        <figure
          src="../umlpictures/class-diagram-org.wamblee.security.authorization.pathcondition.jpg"
          alt="Path condition."/>
        <p>
          Only one type of <code>OperationCondition</code> is implemented which checks if the
          operation is a subclass of a given operation type. 
        </p>
        <figure
          src="../umlpictures/class-diagram-org.wamblee.security.authorization.operationcondition.jpg"
          alt="Operation condition."/>
      </section>
      
      <section>
        <title>Authorization Service</title>
        
        <p>
          The authorization service provides the interface for authorization
          (<code>isAllowed()</code>) as well as methods for managing the authorization rules. 
          The service works by checking each authorization rule in turn until one rule returns 
          <code>GRANTED</code> or <code>DENIED</code>. If none of the rules match, then the service
          returns the result <code>DENIED</code>. The service therefore never returns any other
          result than <code>GRANTED</code> or <code>DENIED</code>.
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.security.authorization.service.jpg" 
          alt="Authorization service."/>
        
        <p>
          The implementation of an authorization service that uses persistent storage for storing
          the rules is done in two steps:
        </p>
        <ul>
          <li><code>DefaultAuthorizationService</code> is a basic POJO which implements the logic
            for authorization. It uses the <code>UserAccessor</code> to obtain the currently logged
            in user information from user management and security. </li>
          <li><code>PersistentAuthorizationService</code> which decorates the service and takes 
            care of caching, persisting, and regularly updating the authorization info w.r.t.
            persistent storage. This is required as a performance optimzation.</li>
        </ul>
        <p>
          This design separates the logic for implementation of the authorization rules from that of
          persistence and caching. 
        </p>
      </section>
      
    </section>
    
    <section id="dynamics">
      <title>Dynamics</title>
      
      <section id="dynamics-servlet-filter">
        <title>Authentication Filter Login</title>
      
        <p>
          The authentication filter intercepts all requests to the web application. In case no user
          identity is available the request is simply forwarded. Otherwise, the user is logged in 
          using JAAS and the request is forwarded using <code>Subject.doAs()</code>.
        </p>
        <figure src="../umlpictures/sequence-diagram-org.wamblee.security.servlet.login.jpg" 
	        alt="Authentication filter and login."/>
      </section>
      
      <section id="dynamics-protected-page">
        <title>Accessing a Protected Page</title>
        <p>
          The sequence diagram shows a scenario where an attempt is made to access a protected page. 
          It obtains the Subject using JAAS API calls and if there is no subject, an exception is 
          thrown.  
        </p>
        <figure src="../umlpictures/sequence-diagram-org.wamblee.tapestry.accessing-protected-page.jpg" 
	        alt="Accessing a protected page."/>
      </section>
      
      <section>
        <title>Authorizing an operation on a resource</title>
        
        <p>
          To check whether an operation is allowed on a resource, the authorization service checks
          each rule in order until one rule returns <code>GRANTED</code> or <code>DENIED</code>.
          Thus the first rule that applies determines the result. If no rules match, <code>DENIED</code>
          is returned. 
        </p>
        <figure
          src="../umlpictures/sequence-diagram-org.wamblee.security.authorization.accesstoresource.jpg"
          alt="Authorizing an operation on a resource."/>
      </section>
      
      <section>
        <title>Authorization logic of <code>UrlAuthorizationRule</code></title>
        
        <p>
          The <code>UrlAuthorizationRule</code> works by first checking all conditions to see if it
          applies. If it applies it returns the configured authorization result. Otherwise, it
          returns <code>UNDECIDED</code> (or <code>UNSUPPORTED_RESOURCE</code>) if it does not apply
          to the specified resource. 
        </p>
        <figure
          src="../umlpictures/sequence-diagram-org.wamblee.security.authorization.urlauthorizationrule.jpg"
          alt="URL authorization rule."/>
      </section>
      
    </section>
    
    <section>
      <title>Design Rules</title>
      <ul>
        <li>
          To use the <code>UrlAuthorizationRule</code>, the user must provide a subclass that
          implements the <code>getResourcePath()</code> method to obtain the path to the resource. 
        </li>
      </ul>
    </section>
  </body>
</document>
