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

nl.talsmasoftware.context.springsecurity.SpringSecurityContextManager Maven / Gradle / Ivy

/*
 * Copyright 2016-2019 Talsma ICT
 *
 * 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
 *
 *         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 nl.talsmasoftware.context.springsecurity;

import nl.talsmasoftware.context.Context;
import nl.talsmasoftware.context.clearable.ClearableContextManager;
import nl.talsmasoftware.context.observer.ContextObservers;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * A context manager that propagates spring-security {@link Authentication} objects
 * into background threads using the {@code ContextAwareExecutorService}.
 * 

* Management of the authentication is fully delegated to the Spring {@link SecurityContextHolder}, * so no additional {@link java.lang.ThreadLocal} variables are used. * * @author Sjoerd Talsma */ public class SpringSecurityContextManager implements ClearableContextManager { /** * Creates a new Spring {@linkplain SecurityContext} and sets the {@linkplain Authentication value} in it. *

* This new value is set in the {@linkplain SecurityContextHolder} and the current {@linkplain Authentication} * is remembered, to be restored when the returned {@link Context} is closed. * * @param value The value to initialize a new context for. * @return A context with the new Authentication, restoring the previous authentication when closed. */ public Context initializeNewContext(Authentication value) { SecurityContext previous = SecurityContextHolder.getContext(); SecurityContext current = SecurityContextHolder.createEmptyContext(); current.setAuthentication(value); SecurityContextHolder.setContext(current); return new AuthenticationContext(current, previous, false); } /** * @return A context object referring to the current {@code Authentication} in the spring security context holder. * Closing the returned context does nothing. */ public Context getActiveContext() { return new AuthenticationContext(SecurityContextHolder.getContext(), null, true); } /** * Clears the Spring {@linkplain SecurityContext} by calling {@linkplain SecurityContextHolder#clearContext()}. */ public void clear() { SecurityContextHolder.clearContext(); } private static final class AuthenticationContext implements Context { private volatile SecurityContext current; private final SecurityContext previous; private final AtomicBoolean closed; private AuthenticationContext(SecurityContext current, SecurityContext previous, boolean alreadyClosed) { this.current = current; this.previous = previous; this.closed = new AtomicBoolean(alreadyClosed); ContextObservers.onActivate(SpringSecurityContextManager.class, auth(current), auth(previous)); } public Authentication getValue() { return auth(current); } public void close() { if (closed.compareAndSet(false, true)) { SecurityContextHolder.setContext(previous); ContextObservers.onDeactivate(SpringSecurityContextManager.class, auth(current), auth(previous)); } } /** * Null-safe {@code getAuthentication()} call * * @param securityContext optional security context to get authentication object from. * @return the authentication object or null if security context itself was null. */ private static Authentication auth(SecurityContext securityContext) { return securityContext == null ? null : securityContext.getAuthentication(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy