1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 module hunt.shiro.session.Session; 20 21 import hunt.util.Common; 22 import hunt.collection; 23 import hunt.shiro.util.Common; 24 // import java.util.Date; 25 26 import hunt.String; 27 28 alias Date = long; 29 30 alias ShiroSession = Session; 31 32 /** 33 * A {@code Session} is a stateful data context associated with a single Subject (user, daemon process, 34 * etc) who interacts with a software system over a period of time. 35 * <p/> 36 * A {@code Session} is intended to be managed by the business tier and accessible via other 37 * tiers without being tied to any given client technology. This is a <em>great</em> benefit to Java 38 * systems, since until now, the only viable session mechanisms were the 39 * {@code javax.servlet.http.HttpSession} or Stateful Session EJB's, which many times 40 * unnecessarily coupled applications to web or ejb technologies. 41 * 42 */ 43 interface Session { 44 45 /** 46 * Returns the unique identifier assigned by the system upon session creation. 47 * <p/> 48 * All return values from this method are expected to have proper {@code toString()}, 49 * {@code equals()}, and {@code hashCode()} implementations. Good candidates for such 50 * an identifier are {@link java.util.UUID UUID}s, {@link java.lang.Integer Integer}s, and 51 * {@link java.lang.string string}s. 52 * 53 * @return The unique identifier assigned to the session upon creation. 54 */ 55 string getId(); 56 57 /** 58 * Returns the time the session was started; that is, the time the system created the instance. 59 * 60 * @return The time the system created the session. 61 */ 62 Date getStartTimestamp(); 63 64 /** 65 * Returns the last time the application received a request or method invocation from the user associated 66 * with this session. Application calls to this method do not affect this access time. 67 * 68 * @return The time the user last interacted with the system. 69 * @see #touch() 70 */ 71 Date getLastAccessTime(); 72 73 /** 74 * Returns the time in milliseconds that the session session may remain idle before expiring. 75 * <ul> 76 * <li>A negative return value means the session will never expire.</li> 77 * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that 78 * length of time.</li> 79 * </ul> 80 * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on 81 * this method is different: Shiro Sessions use millisecond values for timeout whereas 82 * {@code HttpSession.getMaxInactiveInterval} uses seconds. Always use millisecond values with Shiro sessions. 83 * 84 * @return the time in milliseconds the session may remain idle before expiring. 85 * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method. 86 */ 87 long getTimeout(); 88 89 /** 90 * Sets the time in milliseconds that the session may remain idle before expiring. 91 * <ul> 92 * <li>A negative value means the session will never expire.</li> 93 * <li>A non-negative value (0 or greater) means the session expiration will occur if idle for that 94 * length of time.</li> 95 * </ul> 96 * <p/> 97 * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on 98 * this method is different: Shiro Sessions use millisecond values for timeout whereas 99 * {@code HttpSession.getMaxInactiveInterval} uses seconds. Always use millisecond values with Shiro sessions. 100 * 101 * @param maxIdleTimeInMillis the time in milliseconds that the session may remain idle before expiring. 102 * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method. 103 */ 104 void setTimeout(long maxIdleTimeInMillis); 105 106 /** 107 * Returns the host name or IP string of the host that originated this session, or {@code null} 108 * if the host is unknown. 109 * 110 * @return the host name or IP string of the host that originated this session, or {@code null} 111 * if the host address is unknown. 112 */ 113 string getHost(); 114 115 /** 116 * Explicitly updates the {@link #getLastAccessTime() lastAccessTime} of this session to the current time when 117 * this method is invoked. This method can be used to ensure a session does not time out. 118 * <p/> 119 * Most programmers won't use this method directly and will instead rely on the last access time to be updated 120 * automatically as a result of an incoming web request or remote procedure call/method invocation. 121 * <p/> 122 * However, this method is particularly useful when supporting rich-client applications such as 123 * Java Web Start app, Java or Flash applets, etc. Although rare, it is possible in a rich-client 124 * environment that a user continuously interacts with the client-side application without a 125 * server-side method call ever being invoked. If this happens over a long enough period of 126 * time, the user's server-side session could time-out. Again, such cases are rare since most 127 * rich-clients frequently require server-side method invocations. 128 * <p/> 129 * In this example though, the user's session might still be considered valid because 130 * the user is actively "using" the application, just not communicating with the 131 * server. But because no server-side method calls are invoked, there is no way for the server 132 * to know if the user is sitting idle or not, so it must assume so to maintain session 133 * integrity. This {@code touch()} method could be invoked by the rich-client application code during those 134 * times to ensure that the next time a server-side method is invoked, the invocation will not 135 * throw an {@link ExpiredSessionException ExpiredSessionException}. In short terms, it could be used periodically 136 * to ensure a session does not time out. 137 * <p/> 138 * How often this rich-client "maintenance" might occur is entirely dependent upon 139 * the application and would be based on variables such as session timeout configuration, 140 * usage characteristics of the client application, network utilization and application server 141 * performance. 142 * 143 * @throws InvalidSessionException if this session has stopped or expired prior to calling this method. 144 */ 145 void touch(); 146 147 /** 148 * Explicitly stops (invalidates) this session and releases all associated resources. 149 * <p/> 150 * If this session has already been authenticated (i.e. the {@code Subject} that 151 * owns this session has logged-in), calling this method explicitly might have undesired side effects: 152 * <p/> 153 * It is common for a {@code Subject} implementation to retain authentication state in the 154 * {@code Session}. If the session 155 * is explicitly stopped by application code by calling this method directly, it could clear out any 156 * authentication state that might exist, thereby effectively "unauthenticating" the {@code Subject}. 157 * <p/> 158 * As such, you might consider {@link hunt.shiro.subject.Subject#logout logging-out} the 'owning' 159 * {@code Subject} instead of manually calling this method, as a log out is expected to stop the 160 * corresponding session automatically, and also allows framework code to execute additional cleanup logic. 161 * 162 * @throws InvalidSessionException if this session has stopped or expired prior to calling this method. 163 */ 164 void stop(); 165 166 /** 167 * Returns the keys of all the attributes stored under this session. If there are no 168 * attributes, this returns an empty collection. 169 * 170 * @return the keys of all attributes stored under this session, or an empty collection if 171 * there are no session attributes. 172 * @throws InvalidSessionException if this session has stopped or expired prior to calling this method. 173 */ 174 Object[] getAttributeKeys(); 175 176 /** 177 * Returns the object bound to this session identified by the specified key. If there is no 178 * object bound under the key, {@code null} is returned. 179 * 180 * @param key the unique name of the object bound to this session 181 * @return the object bound under the specified {@code key} name or {@code null} if there is 182 * no object bound under that name. 183 * @throws InvalidSessionException if this session has stopped or expired prior to calling 184 * this method. 185 */ 186 Object getAttribute(Object key); 187 188 189 final Object getAttribute(string key) { 190 return getAttribute(new String(key)); 191 } 192 193 /** 194 * Binds the specified {@code value} to this session, uniquely identified by the specified 195 * {@code key} name. If there is already an object bound under the {@code key} name, that 196 * existing object will be replaced by the new {@code value}. 197 * <p/> 198 * If the {@code value} parameter is null, it has the same effect as if 199 * {@link #removeAttribute(Object) removeAttribute} was called. 200 * 201 * @param key the name under which the {@code value} object will be bound in this session 202 * @param value the object to bind in this session. 203 * @throws InvalidSessionException if this session has stopped or expired prior to calling 204 * this method. 205 */ 206 void setAttribute(Object key, Object value); 207 208 final void setAttribute(string key, Object value) { 209 setAttribute(new String(key), value); 210 } 211 212 final void setAttribute(string key, string value) { 213 setAttribute(new String(key), new String(value)); 214 } 215 216 /** 217 * Removes (unbinds) the object bound to this session under the specified {@code key} name. 218 * 219 * @param key the name uniquely identifying the object to remove 220 * @return the object removed or {@code null} if there was no object bound under the name 221 * {@code key}. 222 * @throws InvalidSessionException if this session has stopped or expired prior to calling 223 * this method. 224 */ 225 Object removeAttribute(Object key); 226 227 final Object removeAttribute(string key) { 228 return removeAttribute(new String(key)); 229 } 230 }