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