spring security SessionFixationProtectionStrategy 源码

  • 2022-08-13
  • 浏览 (808)

spring security SessionFixationProtectionStrategy 代码

文件路径:/web/src/main/java/org/springframework/security/web/authentication/session/SessionFixationProtectionStrategy.java

/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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.springframework.security.web.authentication.session;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;

import org.springframework.core.log.LogMessage;

/**
 * Uses {@code HttpServletRequest.invalidate()} to protect against session fixation
 * attacks.
 * <p>
 * Creates a new session for the newly authenticated user if they already have a session
 * (as a defence against session-fixation protection attacks), and copies their session
 * attributes across to the new session. The copying of the attributes can be disabled by
 * setting {@code migrateSessionAttributes} to {@code false} (note that even in this case,
 * internal Spring Security attributes will still be migrated to the new session).
 * <p>
 * This approach will only be effective if your servlet container always assigns a new
 * session Id when a session is invalidated and a new session created by calling
 * {@link HttpServletRequest#getSession()}.
 * <p>
 * <h3>Issues with {@code HttpSessionBindingListener}</h3>
 * <p>
 * The migration of existing attributes to the newly-created session may cause problems if
 * any of the objects implement the {@code HttpSessionBindingListener} interface in a way
 * which makes assumptions about the life-cycle of the object. An example is the use of
 * Spring session-scoped beans, where the initial removal of the bean from the session
 * will cause the {@code DisposableBean} interface to be invoked, in the assumption that
 * the bean is no longer required.
 * <p>
 * We'd recommend that you take account of this when designing your application and do not
 * store attributes which may not function correctly when they are removed and then placed
 * back in the session. Alternatively, you should customize the
 * {@code SessionAuthenticationStrategy} to deal with the issue in an application-specific
 * way.
 *
 * @author Luke Taylor
 * @since 3.0
 */
public class SessionFixationProtectionStrategy extends AbstractSessionFixationProtectionStrategy {

	/**
	 * Indicates that the session attributes of an existing session should be migrated to
	 * the new session. Defaults to <code>true</code>.
	 */
	boolean migrateSessionAttributes = true;

	/**
	 * Called to extract the existing attributes from the session, prior to invalidating
	 * it. If {@code migrateAttributes} is set to {@code false}, only Spring Security
	 * attributes will be retained. All application attributes will be discarded.
	 * <p>
	 * You can override this method to control exactly what is transferred to the new
	 * session.
	 * @param session the session from which the attributes should be extracted
	 * @return the map of session attributes which should be transferred to the new
	 * session
	 */
	protected Map<String, Object> extractAttributes(HttpSession session) {
		return createMigratedAttributeMap(session);
	}

	@Override
	final HttpSession applySessionFixation(HttpServletRequest request) {
		HttpSession session = request.getSession();
		String originalSessionId = session.getId();
		this.logger.debug(LogMessage.of(() -> "Invalidating session with Id '" + originalSessionId + "' "
				+ (this.migrateSessionAttributes ? "and" : "without") + " migrating attributes."));
		Map<String, Object> attributesToMigrate = extractAttributes(session);
		int maxInactiveIntervalToMigrate = session.getMaxInactiveInterval();
		session.invalidate();
		session = request.getSession(true); // we now have a new session
		this.logger.debug(LogMessage.format("Started new session: %s", session.getId()));
		transferAttributes(attributesToMigrate, session);
		if (this.migrateSessionAttributes) {
			session.setMaxInactiveInterval(maxInactiveIntervalToMigrate);
		}
		return session;
	}

	/**
	 * @param attributes the attributes which were extracted from the original session by
	 * {@code extractAttributes}
	 * @param newSession the newly created session
	 */
	void transferAttributes(Map<String, Object> attributes, HttpSession newSession) {
		if (attributes != null) {
			attributes.forEach(newSession::setAttribute);
		}
	}

	@SuppressWarnings("unchecked")
	private HashMap<String, Object> createMigratedAttributeMap(HttpSession session) {
		HashMap<String, Object> attributesToMigrate = new HashMap<>();
		Enumeration<String> enumeration = session.getAttributeNames();
		while (enumeration.hasMoreElements()) {
			String key = enumeration.nextElement();
			if (!this.migrateSessionAttributes && !key.startsWith("SPRING_SECURITY_")) {
				// Only retain Spring Security attributes
				continue;
			}
			attributesToMigrate.put(key, session.getAttribute(key));
		}
		return attributesToMigrate;
	}

	/**
	 * Defines whether attributes should be migrated to a new session or not. Has no
	 * effect if you override the {@code extractAttributes} method.
	 * <p>
	 * Attributes used by Spring Security (to store cached requests, for example) will
	 * still be retained by default, even if you set this value to {@code false}.
	 * @param migrateSessionAttributes whether the attributes from the session should be
	 * transferred to the new, authenticated session.
	 */
	public void setMigrateSessionAttributes(boolean migrateSessionAttributes) {
		this.migrateSessionAttributes = migrateSessionAttributes;
	}

}

相关信息

spring security 源码目录

相关文章

spring security AbstractSessionFixationProtectionStrategy 源码

spring security ChangeSessionIdAuthenticationStrategy 源码

spring security CompositeSessionAuthenticationStrategy 源码

spring security ConcurrentSessionControlAuthenticationStrategy 源码

spring security NullAuthenticatedSessionStrategy 源码

spring security RegisterSessionAuthenticationStrategy 源码

spring security SessionAuthenticationException 源码

spring security SessionAuthenticationStrategy 源码

spring security SessionFixationProtectionEvent 源码

spring security package-info 源码

0  赞