001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.shiro.session;
020
021import java.io.Serializable;
022import java.util.Collection;
023import java.util.Date;
024
025/**
026 * A {@code Session} is a stateful data context associated with a single Subject (user, daemon process,
027 * etc) who interacts with a software system over a period of time.
028 * <p/>
029 * A {@code Session} is intended to be managed by the business tier and accessible via other
030 * tiers without being tied to any given client technology.  This is a <em>great</em> benefit to Java
031 * systems, since until now, the only viable session mechanisms were the
032 * {@code javax.servlet.http.HttpSession} or Stateful Session EJB's, which many times
033 * unnecessarily coupled applications to web or ejb technologies.
034 *
035 * @since 0.1
036 */
037public interface Session {
038
039    /**
040     * Returns the unique identifier assigned by the system upon session creation.
041     * <p/>
042     * All return values from this method are expected to have proper {@code toString()},
043     * {@code equals()}, and {@code hashCode()} implementations. Good candidates for such
044     * an identifier are {@link java.util.UUID UUID}s, {@link java.lang.Integer Integer}s, and
045     * {@link java.lang.String String}s.
046     *
047     * @return The unique identifier assigned to the session upon creation.
048     */
049    Serializable getId();
050
051    /**
052     * Returns the time the session was started; that is, the time the system created the instance.
053     *
054     * @return The time the system created the session.
055     */
056    Date getStartTimestamp();
057
058    /**
059     * Returns the last time the application received a request or method invocation from the user associated
060     * with this session.  Application calls to this method do not affect this access time.
061     *
062     * @return The time the user last interacted with the system.
063     * @see #touch()
064     */
065    Date getLastAccessTime();
066
067    /**
068     * Returns the time in milliseconds that the session session may remain idle before expiring.
069     * <ul>
070     * <li>A negative return value means the session will never expire.</li>
071     * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
072     * length of time.</li>
073     * </ul>
074     * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
075     * this method is different: Shiro Sessions use millisecond values for timeout whereas
076     * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Shiro sessions.
077     *
078     * @return the time in milliseconds the session may remain idle before expiring.
079     * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
080     * @since 0.2
081     */
082    long getTimeout() throws InvalidSessionException;
083
084    /**
085     * Sets the time in milliseconds that the session may remain idle before expiring.
086     * <ul>
087     * <li>A negative value means the session will never expire.</li>
088     * <li>A non-negative value (0 or greater) means the session expiration will occur if idle for that
089     * length of time.</li>
090     * </ul>
091     * <p/>
092     * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
093     * this method is different: Shiro Sessions use millisecond values for timeout whereas
094     * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Shiro sessions.
095     *
096     * @param maxIdleTimeInMillis the time in milliseconds that the session may remain idle before expiring.
097     * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
098     * @since 0.2
099     */
100    void setTimeout(long maxIdleTimeInMillis) throws InvalidSessionException;
101
102    /**
103     * Returns the host name or IP string of the host that originated this session, or {@code null}
104     * if the host is unknown.
105     *
106     * @return the host name or IP string of the host that originated this session, or {@code null}
107     *         if the host address is unknown.
108     */
109    String getHost();
110
111    /**
112     * Explicitly updates the {@link #getLastAccessTime() lastAccessTime} of this session to the current time when
113     * this method is invoked.  This method can be used to ensure a session does not time out.
114     * <p/>
115     * Most programmers won't use this method directly and will instead rely on the last access time to be updated
116     * automatically as a result of an incoming web request or remote procedure call/method invocation.
117     * <p/>
118     * However, this method is particularly useful when supporting rich-client applications such as
119     * Java Web Start appp, Java or Flash applets, etc.  Although rare, it is possible in a rich-client
120     * environment that a user continuously interacts with the client-side application without a
121     * server-side method call ever being invoked.  If this happens over a long enough period of
122     * time, the user's server-side session could time-out.  Again, such cases are rare since most
123     * rich-clients frequently require server-side method invocations.
124     * <p/>
125     * In this example though, the user's session might still be considered valid because
126     * the user is actively &quot;using&quot; the application, just not communicating with the
127     * server. But because no server-side method calls are invoked, there is no way for the server
128     * to know if the user is sitting idle or not, so it must assume so to maintain session
129     * integrity.  This {@code touch()} method could be invoked by the rich-client application code during those
130     * times to ensure that the next time a server-side method is invoked, the invocation will not
131     * throw an {@link ExpiredSessionException ExpiredSessionException}.  In short terms, it could be used periodically
132     * to ensure a session does not time out.
133     * <p/>
134     * How often this rich-client &quot;maintenance&quot; might occur is entirely dependent upon
135     * the application and would be based on variables such as session timeout configuration,
136     * usage characteristics of the client application, network utilization and application server
137     * performance.
138     *
139     * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
140     */
141    void touch() throws InvalidSessionException;
142
143    /**
144     * Explicitly stops (invalidates) this session and releases all associated resources.
145     * <p/>
146     * If this session has already been authenticated (i.e. the {@code Subject} that
147     * owns this session has logged-in), calling this method explicitly might have undesired side effects:
148     * <p/>
149     * It is common for a {@code Subject} implementation to retain authentication state in the
150     * {@code Session}.  If the session
151     * is explicitly stopped by application code by calling this method directly, it could clear out any
152     * authentication state that might exist, thereby effectively &quot;unauthenticating&quot; the {@code Subject}.
153     * <p/>
154     * As such, you might consider {@link org.apache.shiro.subject.Subject#logout logging-out} the 'owning'
155     * {@code Subject} instead of manually calling this method, as a log out is expected to stop the
156     * corresponding session automatically, and also allows framework code to execute additional cleanup logic.
157     *
158     * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
159     */
160    void stop() throws InvalidSessionException;
161
162    /**
163     * Returns the keys of all the attributes stored under this session.  If there are no
164     * attributes, this returns an empty collection.
165     *
166     * @return the keys of all attributes stored under this session, or an empty collection if
167     *         there are no session attributes.
168     * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
169     * @since 0.2
170     */
171    Collection<Object> getAttributeKeys() throws InvalidSessionException;
172
173    /**
174     * Returns the object bound to this session identified by the specified key.  If there is no
175     * object bound under the key, {@code null} is returned.
176     *
177     * @param key the unique name of the object bound to this session
178     * @return the object bound under the specified {@code key} name or {@code null} if there is
179     *         no object bound under that name.
180     * @throws InvalidSessionException if this session has stopped or expired prior to calling
181     *                                 this method.
182     */
183    Object getAttribute(Object key) throws InvalidSessionException;
184
185    /**
186     * Binds the specified {@code value} to this session, uniquely identified by the specifed
187     * {@code key} name.  If there is already an object bound under the {@code key} name, that
188     * existing object will be replaced by the new {@code value}.
189     * <p/>
190     * If the {@code value} parameter is null, it has the same effect as if
191     * {@link #removeAttribute(Object) removeAttribute} was called.
192     *
193     * @param key   the name under which the {@code value} object will be bound in this session
194     * @param value the object to bind in this session.
195     * @throws InvalidSessionException if this session has stopped or expired prior to calling
196     *                                 this method.
197     */
198    void setAttribute(Object key, Object value) throws InvalidSessionException;
199
200    /**
201     * Removes (unbinds) the object bound to this session under the specified {@code key} name.
202     *
203     * @param key the name uniquely identifying the object to remove
204     * @return the object removed or {@code null} if there was no object bound under the name
205     *         {@code key}.
206     * @throws InvalidSessionException if this session has stopped or expired prior to calling
207     *                                 this method.
208     */
209    Object removeAttribute(Object key) throws InvalidSessionException;
210}