View Javadoc

    1   /* Copyright 2004 Acegi Technology Pty Limited
    2    *
    3    * Licensed under the Apache License, Version 2.0 (the "License");
    4    * you may not use this file except in compliance with the License.
    5    * You may obtain a copy of the License at
    6    *
    7    *     http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15
    16  package org.acegisecurity.acl.basic;
    17
    18  import org.acegisecurity.Authentication;
    19  import org.acegisecurity.GrantedAuthority;
    20  import org.acegisecurity.acl.AclEntry;
    21  import org.acegisecurity.userdetails.UserDetails;
    22
    23  import org.apache.commons.logging.Log;
    24  import org.apache.commons.logging.LogFactory;
    25
    26  import java.util.List;
    27  import java.util.Vector;
    28
    29
    30  /***
    31   * Simple implementation of {@link EffectiveAclsResolver}.
    32   *
    33   * <P>
    34   * This implementation does not need to understand the "recipient" types
    35   * presented in a <code>BasicAclEntry</code> because it merely delegates to
    36   * the detected {@link Authentication#getPrincipal()} or {@link
    37   * Authentication#getAuthorities()}. The principal object or granted
    38   * authorities object has its <code>Object.equals(recipient)</code> method
    39   * called to make the decision as to whether the recipient in the
    40   * <code>BasicAclEntry</code> is the same as the principal or granted
    41   * authority.
    42   * </p>
    43   *
    44   * <P>
    45   * This class should prove an adequate ACLs resolver if you're using standard
    46   * Acegi Security classes. This is because the typical
    47   * <code>Authentication</code> token is
    48   * <code>UsernamePasswordAuthenticationToken</code>, which for its
    49   * <code>principal</code> is usually a <code>String</code>. The
    50   * <code>GrantedAuthorityImpl</code> is typically used for granted
    51   * authorities, which tests for equality based on a <code>String</code>. This
    52   * means <code>BasicAclDao</code>s simply need to return a <code>String</code>
    53   * to represent the recipient. If you use non-<code>String</code> objects, you
    54   * will probably require an alternative <code>EffectiveAclsResolver</code>.
    55   * </p>
    56   *
    57   * @author Ben Alex
    58   * @version $Id: GrantedAuthorityEffectiveAclsResolver.java,v 1.6 2005/11/29 13:10:11 benalex Exp $
    59   */
    60  public class GrantedAuthorityEffectiveAclsResolver
    61      implements EffectiveAclsResolver {
    62      //~ Static fields/initializers =============================================
    63
    64      private static final Log logger = LogFactory.getLog(GrantedAuthorityEffectiveAclsResolver.class);
    65
    66      //~ Methods ================================================================
    67
    68      public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls,
    69          Authentication filteredBy) {
    70          if ((allAcls == null) || (allAcls.length == 0)) {
    71              return null;
    72          }
    73
    74          List list = new Vector();
    75
    76          if (logger.isDebugEnabled()) {
    77              logger.debug("Locating AclEntry[]s (from set of "
    78                  + ((allAcls == null) ? 0 : allAcls.length)
    79                  + ") that apply to Authentication: " + filteredBy);
    80          }
    81
    82          for (int i = 0; i < allAcls.length; i++) {
    83              if (!(allAcls[i] instanceof BasicAclEntry)) {
    84                  continue;
    85              }
    86
    87              Object recipient = ((BasicAclEntry) allAcls[i])
    88                  .getRecipient();
    89
    90              // Allow the Authentication's getPrincipal to decide whether
    91              // the presented recipient is "equal" (allows BasicAclDaos to
    92              // return Strings rather than proper objects in simple cases)
    93              if (filteredBy.getPrincipal().equals(recipient)) {
    94                  if (logger.isDebugEnabled()) {
    95                      logger.debug("Principal matches AclEntry recipient: "
    96                          + recipient);
    97                  }
    98
    99                  list.add(allAcls[i]);
    100             } else if (filteredBy.getPrincipal() instanceof UserDetails
    101                 && ((UserDetails) filteredBy.getPrincipal()).getUsername()
    102                     .equals(recipient)) {
    103                 if (logger.isDebugEnabled()) {
    104                     logger.debug(
    105                         "Principal (from UserDetails) matches AclEntry recipient: "
    106                         + recipient);
    107                 }
    108
    109                 list.add(allAcls[i]);
    110             } else {
    111                 // No direct match against principal; try each authority.
    112                 // As with the principal, allow each of the Authentication's
    113                 // granted authorities to decide whether the presented
    114                 // recipient is "equal"
    115                 GrantedAuthority[] authorities = filteredBy.getAuthorities();
    116
    117                 if ((authorities == null) || (authorities.length == 0)) {
    118                     if (logger.isDebugEnabled()) {
    119                         logger.debug(
    120                             "Did not match principal and there are no granted authorities, so cannot compare with recipient: "
    121                             + recipient);
    122                     }
    123
    124                     continue;
    125                 }
    126
    127                 for (int k = 0; k < authorities.length; k++) {
    128                     if (authorities[k].equals(recipient)) {
    129                         if (logger.isDebugEnabled()) {
    130                             logger.debug("GrantedAuthority: " + authorities[k]
    131                                 + " matches recipient: " + recipient);
    132                         }
    133
    134                         list.add(allAcls[i]);
    135                     }
    136                 }
    137             }
    138         }
    139
    140         // return null if appropriate (as per interface contract)
    141         if (list.size() > 0) {
    142             if (logger.isDebugEnabled()) {
    143                 logger.debug("Returning effective AclEntry array with "
    144                     + list.size() + " elements");
    145             }
    146
    147             return (BasicAclEntry[]) list.toArray(new BasicAclEntry[] {});
    148         } else {
    149             if (logger.isDebugEnabled()) {
    150                 logger.debug(
    151                     "Returning null AclEntry array as zero effective AclEntrys found");
    152             }
    153
    154             return null;
    155         }
    156     }
    157 }