View Javadoc

    1   /*
    2    * Copyright 2007 University Corporation for Advanced Internet Development, Inc.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    * http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package edu.internet2.middleware.shibboleth.idp.session.impl;
    18
    19  import java.security.SecureRandom;
    20
    21  import org.apache.commons.ssl.util.Hex;
    22  import org.opensaml.util.storage.StorageService;
    23  import org.opensaml.xml.util.DatatypeHelper;
    24  import org.slf4j.Logger;
    25  import org.slf4j.LoggerFactory;
    26  import org.slf4j.MDC;
    27
    28  import edu.internet2.middleware.shibboleth.common.session.SessionManager;
    29  import edu.internet2.middleware.shibboleth.idp.session.Session;
    30
    31  /** Manager of IdP sessions. */
    32  public class SessionManagerImpl implements SessionManager<Session> {
    33
    34      /** Class logger. */
    35      private final Logger log = LoggerFactory.getLogger(SessionManagerImpl.class);
    36
    37      /** Number of random bits within a session ID. */
    38      private final int sessionIDSize = 32;
    39
    40      /** A {@link SecureRandom} PRNG to generate session IDs. */
    41      private final SecureRandom prng = new SecureRandom();
    42
    43      /** Backing service used to store sessions. */
    44      private StorageService<String, SessionManagerEntry> sessionStore;
    45
    46      /** Partition in which entries are stored. */
    47      private String partition;
    48
    49      /** Lifetime, in milliseconds, of session. */
    50      private long sessionLifetime;
    51
    52      /**
    53       * Constructor.
    54       *
    55       * @param storageService service used to store sessions
    56       * @param lifetime lifetime, in milliseconds, of sessions
    57       */
    58      public SessionManagerImpl(StorageService<String, SessionManagerEntry> storageService, long lifetime) {
    59          sessionStore = storageService;
    60          partition = "session";
    61          sessionLifetime = lifetime;
    62      }
    63
    64      /**
    65       * Constructor.
    66       *
    67       * @param storageService service used to store session
    68       * @param storageParition partition in which sessions are stored
    69       * @param lifetime lifetime, in milliseconds, of sessions
    70       */
    71      public SessionManagerImpl(StorageService<String, SessionManagerEntry> storageService, String storageParition,
    72              long lifetime) {
    73          sessionStore = storageService;
    74          if (!DatatypeHelper.isEmpty(storageParition)) {
    75              partition = DatatypeHelper.safeTrim(storageParition);
    76          } else {
    77              partition = "session";
    78          }
    79          sessionLifetime = lifetime;
    80      }
    81
    82      /** {@inheritDoc} */
    83      public Session createSession() {
    84          // generate a random session ID
    85          byte[] sid = new byte[sessionIDSize];
    86          prng.nextBytes(sid);
    87          String sessionID = Hex.encode(sid);
    88
    89          byte[] sessionSecret = new byte[16];
    90          prng.nextBytes(sessionSecret);
    91
    92          Session session = new SessionImpl(sessionID, sessionSecret, sessionLifetime);
    93          SessionManagerEntry sessionEntry = new SessionManagerEntry(session, sessionLifetime);
    94          sessionStore.put(partition, sessionID, sessionEntry);
    95
    96          MDC.put("idpSessionId", sessionID);
    97          log.trace("Created session {}", sessionID);
    98          return session;
    99      }
    100
    101     /** {@inheritDoc} */
    102     public Session createSession(String principal) {
    103         // generate a random session ID
    104         byte[] sid = new byte[sessionIDSize];
    105         prng.nextBytes(sid);
    106         String sessionID = Hex.encode(sid);
    107
    108         byte[] sessionSecret = new byte[16];
    109         prng.nextBytes(sessionSecret);
    110
    111         Session session = new SessionImpl(sessionID, sessionSecret, sessionLifetime);
    112         SessionManagerEntry sessionEntry = new SessionManagerEntry(session, sessionLifetime);
    113         sessionStore.put(partition, sessionID, sessionEntry);
    114
    115         MDC.put("idpSessionId", sessionID);
    116         log.trace("Created session {}", sessionID);
    117         return session;
    118     }
    119
    120     /** {@inheritDoc} */
    121     public void destroySession(String sessionID) {
    122         if (sessionID == null) {
    123             return;
    124         }
    125
    126         SessionManagerEntry sessionEntry = sessionStore.get(partition, sessionID);
    127         if (sessionEntry == null) {
    128             return;
    129         }
    130         for(String sessionIndex : sessionEntry.getSessionIndexes()){
    131             sessionStore.remove(partition, sessionIndex);
    132         }
    133         sessionStore.remove(partition, sessionID);
    134     }
    135
    136     /** {@inheritDoc} */
    137     public Session getSession(String sessionID) {
    138         if (sessionID == null) {
    139             return null;
    140         }
    141
    142         SessionManagerEntry sessionEntry = sessionStore.get(partition, sessionID);
    143         if (sessionEntry == null) {
    144             return null;
    145         }
    146
    147         if (sessionEntry.isExpired()) {
    148             destroySession(sessionEntry.getSessionId());
    149             return null;
    150         } else {
    151             return sessionEntry.getSession();
    152         }
    153     }
    154
    155     /** {@inheritDoc} */
    156     public boolean indexSession(Session session, String index) {
    157         if (sessionStore.contains(partition, index)) {
    158             return false;
    159         }
    160
    161         SessionManagerEntry sessionEntry = sessionStore.get(partition, session.getSessionID());
    162         if (sessionEntry == null) {
    163             return false;
    164         }
    165
    166         if (sessionEntry.getSessionIndexes().contains(index)) {
    167             return true;
    168         }
    169
    170         sessionEntry.getSessionIndexes().add(index);
    171         sessionStore.put(partition, index, sessionEntry);
    172         log.trace("Added index {} to session {}", index, session.getSessionID());
    173         return true;
    174     }
    175
    176     /** {@inheritDoc} */
    177     public void removeSessionIndex(String index) {
    178         SessionManagerEntry sessionEntry = sessionStore.remove(partition, index);
    179         if (sessionEntry != null) {
    180             log.trace("Removing index {} for session {}", index, sessionEntry.getSessionId());
    181             sessionEntry.getSessionIndexes().remove(index);
    182         }
    183     }
    184 }