001/* 002 * Copyright 2002-2014 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.socket.server.support; 018 019import java.util.Collection; 020import java.util.Collections; 021import java.util.Enumeration; 022import java.util.Map; 023import javax.servlet.http.HttpSession; 024 025import org.springframework.http.server.ServerHttpRequest; 026import org.springframework.http.server.ServerHttpResponse; 027import org.springframework.http.server.ServletServerHttpRequest; 028import org.springframework.web.socket.WebSocketHandler; 029import org.springframework.web.socket.WebSocketSession; 030import org.springframework.web.socket.server.HandshakeInterceptor; 031 032/** 033 * An interceptor to copy information from the HTTP session to the "handshake 034 * attributes" map to made available via{@link WebSocketSession#getAttributes()}. 035 * 036 * <p>Copies a subset or all HTTP session attributes and/or the HTTP session id 037 * under the key {@link #HTTP_SESSION_ID_ATTR_NAME}. 038 * 039 * @author Rossen Stoyanchev 040 * @since 4.0 041 */ 042public class HttpSessionHandshakeInterceptor implements HandshakeInterceptor { 043 044 /** 045 * The name of the attribute under which the HTTP session id is exposed when 046 * {@link #setCopyHttpSessionId(boolean) copyHttpSessionId} is "true". 047 */ 048 public static final String HTTP_SESSION_ID_ATTR_NAME = "HTTP.SESSION.ID"; 049 050 051 private final Collection<String> attributeNames; 052 053 private boolean copyAllAttributes; 054 055 private boolean copyHttpSessionId = true; 056 057 private boolean createSession; 058 059 060 /** 061 * Default constructor for copying all HTTP session attributes and the HTTP 062 * session id. 063 * @see #setCopyAllAttributes 064 * @see #setCopyHttpSessionId 065 */ 066 public HttpSessionHandshakeInterceptor() { 067 this.attributeNames = Collections.emptyList(); 068 this.copyAllAttributes = true; 069 } 070 071 /** 072 * Constructor for copying specific HTTP session attributes and the HTTP 073 * session id. 074 * @param attributeNames session attributes to copy 075 * @see #setCopyAllAttributes 076 * @see #setCopyHttpSessionId 077 */ 078 public HttpSessionHandshakeInterceptor(Collection<String> attributeNames) { 079 this.attributeNames = Collections.unmodifiableCollection(attributeNames); 080 this.copyAllAttributes = false; 081 } 082 083 084 /** 085 * Return the configured attribute names to copy (read-only). 086 */ 087 public Collection<String> getAttributeNames() { 088 return this.attributeNames; 089 } 090 091 /** 092 * Whether to copy all attributes from the HTTP session. If set to "true", 093 * any explicitly configured attribute names are ignored. 094 * <p>By default this is set to either "true" or "false" depending on which 095 * constructor was used (default or with attribute names respectively). 096 * @param copyAllAttributes whether to copy all attributes 097 */ 098 public void setCopyAllAttributes(boolean copyAllAttributes) { 099 this.copyAllAttributes = copyAllAttributes; 100 } 101 102 /** 103 * Whether to copy all HTTP session attributes. 104 */ 105 public boolean isCopyAllAttributes() { 106 return this.copyAllAttributes; 107 } 108 109 /** 110 * Whether the HTTP session id should be copied to the handshake attributes 111 * under the key {@link #HTTP_SESSION_ID_ATTR_NAME}. 112 * <p>By default this is "true". 113 * @param copyHttpSessionId whether to copy the HTTP session id. 114 */ 115 public void setCopyHttpSessionId(boolean copyHttpSessionId) { 116 this.copyHttpSessionId = copyHttpSessionId; 117 } 118 119 /** 120 * Whether to copy the HTTP session id to the handshake attributes. 121 */ 122 public boolean isCopyHttpSessionId() { 123 return this.copyHttpSessionId; 124 } 125 126 /** 127 * Whether to allow the HTTP session to be created while accessing it. 128 * <p>By default set to {@code false}. 129 * @see javax.servlet.http.HttpServletRequest#getSession(boolean) 130 */ 131 public void setCreateSession(boolean createSession) { 132 this.createSession = createSession; 133 } 134 135 /** 136 * Whether the HTTP session is allowed to be created. 137 */ 138 public boolean isCreateSession() { 139 return this.createSession; 140 } 141 142 143 @Override 144 public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, 145 WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { 146 147 HttpSession session = getSession(request); 148 if (session != null) { 149 if (isCopyHttpSessionId()) { 150 attributes.put(HTTP_SESSION_ID_ATTR_NAME, session.getId()); 151 } 152 Enumeration<String> names = session.getAttributeNames(); 153 while (names.hasMoreElements()) { 154 String name = names.nextElement(); 155 if (isCopyAllAttributes() || getAttributeNames().contains(name)) { 156 attributes.put(name, session.getAttribute(name)); 157 } 158 } 159 } 160 return true; 161 } 162 163 private HttpSession getSession(ServerHttpRequest request) { 164 if (request instanceof ServletServerHttpRequest) { 165 ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request; 166 return serverRequest.getServletRequest().getSession(isCreateSession()); 167 } 168 return null; 169 } 170 171 @Override 172 public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, 173 WebSocketHandler wsHandler, Exception ex) { 174 } 175 176}