blob: 99630a096512b08dd3ce100ec5f09016cada8ff9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.shiro.web.session;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpSession;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
/**
* {@link Session Session} implementation that is backed entirely by a standard servlet container
* {@link HttpSession HttpSession} instance. It does not interact with any of Shiro's session-related components
* {@code SessionManager}, {@code SecurityManager}, etc, and instead satisfies all method implementations by interacting
* with a servlet container provided {@link HttpSession HttpSession} instance.
*
* @since 1.0
*/
public class HttpServletSession implements Session {
private static final String HOST_SESSION_KEY = HttpServletSession.class.getName() + ".HOST_SESSION_KEY";
private static final String TOUCH_OBJECT_SESSION_KEY = HttpServletSession.class.getName() + ".TOUCH_OBJECT_SESSION_KEY";
private HttpSession httpSession = null;
public HttpServletSession(HttpSession httpSession, String host) {
if (httpSession == null) {
String msg = "HttpSession constructor argument cannot be null.";
throw new IllegalArgumentException(msg);
}
if (httpSession instanceof ShiroHttpSession) {
String msg = "HttpSession constructor argument cannot be an instance of ShiroHttpSession. This " +
"is enforced to prevent circular dependencies and infinite loops.";
throw new IllegalArgumentException(msg);
}
this.httpSession = httpSession;
if (StringUtils.hasText(host)) {
setHost(host);
}
}
public Serializable getId() {
return httpSession.getId();
}
public Date getStartTimestamp() {
return new Date(httpSession.getCreationTime());
}
public Date getLastAccessTime() {
return new Date(httpSession.getLastAccessedTime());
}
public long getTimeout() throws InvalidSessionException {
try {
return httpSession.getMaxInactiveInterval() * 1000L;
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
public void setTimeout(long maxIdleTimeInMillis) throws InvalidSessionException {
try {
int timeout = Long.valueOf(maxIdleTimeInMillis / 1000).intValue();
httpSession.setMaxInactiveInterval(timeout);
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
protected void setHost(String host) {
setAttribute(HOST_SESSION_KEY, host);
}
public String getHost() {
return (String) getAttribute(HOST_SESSION_KEY);
}
public void touch() throws InvalidSessionException {
//just manipulate the session to update the access time:
try {
httpSession.setAttribute(TOUCH_OBJECT_SESSION_KEY, TOUCH_OBJECT_SESSION_KEY);
httpSession.removeAttribute(TOUCH_OBJECT_SESSION_KEY);
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
public void stop() throws InvalidSessionException {
try {
httpSession.invalidate();
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
public Collection<Object> getAttributeKeys() throws InvalidSessionException {
try {
Enumeration namesEnum = httpSession.getAttributeNames();
Collection<Object> keys = null;
if (namesEnum != null) {
keys = new ArrayList<Object>();
while (namesEnum.hasMoreElements()) {
keys.add(namesEnum.nextElement());
}
}
return keys;
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
private static String assertString(Object key) {
if (!(key instanceof String)) {
String msg = "HttpSession based implementations of the Shiro Session interface requires attribute keys " +
"to be String objects. The HttpSession class does not support anything other than String keys.";
throw new IllegalArgumentException(msg);
}
return (String) key;
}
public Object getAttribute(Object key) throws InvalidSessionException {
try {
return httpSession.getAttribute(assertString(key));
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
public void setAttribute(Object key, Object value) throws InvalidSessionException {
try {
httpSession.setAttribute(assertString(key), value);
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
public Object removeAttribute(Object key) throws InvalidSessionException {
try {
String sKey = assertString(key);
Object removed = httpSession.getAttribute(sKey);
httpSession.removeAttribute(sKey);
return removed;
} catch (Exception e) {
throw new InvalidSessionException(e);
}
}
}