All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.security.web.context.SecurityContextPersistenceFilter Maven / Gradle / Ivy

/*
 * Copyright 2002-2016 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.context;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.core.log.LogMessage;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

/**
 * Populates the {@link SecurityContextHolder} with information obtained from the
 * configured {@link SecurityContextRepository} prior to the request and stores it back in
 * the repository once the request has completed and clearing the context holder. By
 * default it uses an {@link HttpSessionSecurityContextRepository}. See this class for
 * information HttpSession related configuration options.
 * 

* This filter will only execute once per request, to resolve servlet container * (specifically Weblogic) incompatibilities. *

* This filter MUST be executed BEFORE any authentication processing mechanisms. * Authentication processing mechanisms (e.g. BASIC, CAS processing filters etc) expect * the SecurityContextHolder to contain a valid SecurityContext * by the time they execute. *

* This is essentially a refactoring of the old * HttpSessionContextIntegrationFilter to delegate the storage issues to a * separate strategy, allowing for more customization in the way the security context is * maintained between requests. *

* The forceEagerSessionCreation property can be used to ensure that a session is * always available before the filter chain executes (the default is false, * as this is resource intensive and not recommended). * * @author Luke Taylor * @since 3.0 */ public class SecurityContextPersistenceFilter extends GenericFilterBean { static final String FILTER_APPLIED = "__spring_security_scpf_applied"; private SecurityContextRepository repo; private boolean forceEagerSessionCreation = false; public SecurityContextPersistenceFilter() { this(new HttpSessionSecurityContextRepository()); } public SecurityContextPersistenceFilter(SecurityContextRepository repo) { this.repo = repo; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain); } private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // ensure that filter is only applied once per request if (request.getAttribute(FILTER_APPLIED) != null) { chain.doFilter(request, response); return; } request.setAttribute(FILTER_APPLIED, Boolean.TRUE); if (this.forceEagerSessionCreation) { HttpSession session = request.getSession(); if (this.logger.isDebugEnabled() && session.isNew()) { this.logger.debug(LogMessage.format("Created session %s eagerly", session.getId())); } } HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder); try { SecurityContextHolder.setContext(contextBeforeChainExecution); if (contextBeforeChainExecution.getAuthentication() == null) { logger.debug("Set SecurityContextHolder to empty SecurityContext"); } else { if (this.logger.isDebugEnabled()) { this.logger .debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution)); } } chain.doFilter(holder.getRequest(), holder.getResponse()); } finally { SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); // Crucial removal of SecurityContextHolder contents before anything else. SecurityContextHolder.clearContext(); this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); request.removeAttribute(FILTER_APPLIED); this.logger.debug("Cleared SecurityContextHolder to complete request"); } } public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) { this.forceEagerSessionCreation = forceEagerSessionCreation; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy