1
0
mirror of synced 2026-08-04 17:27:13 +00:00

Merge branch '6.0.x' into 6.1.x

Closes gh-13883
This commit is contained in:
Marcus Da Coregio
2023-09-29 11:46:48 -03:00
1173 changed files with 10937 additions and 8789 deletions
@@ -148,7 +148,7 @@ public class FilterChainProxy extends GenericFilterBean {
private static final String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private List<SecurityFilterChain> filterChains;
@@ -193,7 +193,7 @@ public class FilterChainProxy extends GenericFilterBean {
catch (Exception ex) {
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
Throwable requestRejectedException = this.throwableAnalyzer
.getFirstThrowableOfType(RequestRejectedException.class, causeChain);
.getFirstThrowableOfType(RequestRejectedException.class, causeChain);
if (!(requestRejectedException instanceof RequestRejectedException)) {
throw ex;
}
@@ -336,17 +336,21 @@ public class FilterInvocation {
return invokeDefaultMethodForJdk8(proxy, method, args);
}
return MethodHandles.lookup()
.findSpecial(method.getDeclaringClass(), method.getName(),
MethodType.methodType(method.getReturnType(), new Class[0]), method.getDeclaringClass())
.bindTo(proxy).invokeWithArguments(args);
.findSpecial(method.getDeclaringClass(), method.getName(),
MethodType.methodType(method.getReturnType(), new Class[0]), method.getDeclaringClass())
.bindTo(proxy)
.invokeWithArguments(args);
}
private Object invokeDefaultMethodForJdk8(Object proxy, Method method, Object[] args) throws Throwable {
Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class);
constructor.setAccessible(true);
Class<?> clazz = method.getDeclaringClass();
return constructor.newInstance(clazz).in(clazz).unreflectSpecial(method, clazz).bindTo(proxy)
.invokeWithArguments(args);
return constructor.newInstance(clazz)
.in(clazz)
.unreflectSpecial(method, clazz)
.bindTo(proxy)
.invokeWithArguments(args);
}
private boolean isJdk8OrEarlier() {
@@ -78,7 +78,7 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
return (req, res) -> {
AroundFilterObservation parent = observation((HttpServletRequest) req);
Observation observation = Observation.createNotStarted(SECURED_OBSERVATION_NAME, this.registry)
.contextualName("secured request");
.contextualName("secured request");
parent.wrap(FilterObservation.create(observation).wrap(original)).doFilter(req, res);
};
}
@@ -86,7 +86,7 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
private FilterChain wrapUnsecured(FilterChain original) {
return (req, res) -> {
Observation observation = Observation.createNotStarted(UNSECURED_OBSERVATION_NAME, this.registry)
.contextualName("unsecured request");
.contextualName("unsecured request");
FilterObservation.create(observation).wrap(original).doFilter(req, res);
};
}
@@ -571,10 +571,10 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
@Override
public KeyValues getLowCardinalityKeyValues(FilterChainObservationContext context) {
return KeyValues.of(CHAIN_SIZE_NAME, String.valueOf(context.getChainSize()))
.and(CHAIN_POSITION_NAME, String.valueOf(context.getChainPosition()))
.and(FILTER_SECTION_NAME, context.getFilterSection())
.and(FILTER_NAME, (StringUtils.hasText(context.getFilterName())) ? context.getFilterName()
: KeyValue.NONE_VALUE);
.and(CHAIN_POSITION_NAME, String.valueOf(context.getChainPosition()))
.and(FILTER_SECTION_NAME, context.getFilterSection())
.and(FILTER_NAME,
(StringUtils.hasText(context.getFilterName())) ? context.getFilterName() : KeyValue.NONE_VALUE);
}
@Override
@@ -90,7 +90,7 @@ public class DefaultWebInvocationPrivilegeEvaluator implements WebInvocationPriv
Assert.notNull(uri, "uri parameter is required");
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
Collection<ConfigAttribute> attributes = this.securityInterceptor.obtainSecurityMetadataSource()
.getAttributes(filterInvocation);
.getAttributes(filterInvocation);
if (attributes == null) {
return (!this.securityInterceptor.isRejectPublicInvocations());
}
@@ -84,7 +84,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class ExceptionTranslationFilter extends GenericFilterBean implements MessageSourceAware {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl();
@@ -132,10 +132,10 @@ public class ExceptionTranslationFilter extends GenericFilterBean implements Mes
// Try to extract a SpringSecurityException from the stacktrace
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
RuntimeException securityException = (AuthenticationException) this.throwableAnalyzer
.getFirstThrowableOfType(AuthenticationException.class, causeChain);
.getFirstThrowableOfType(AuthenticationException.class, causeChain);
if (securityException == null) {
securityException = (AccessDeniedException) this.throwableAnalyzer
.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
}
if (securityException == null) {
rethrow(ex);
@@ -60,7 +60,7 @@ public final class WebExpressionAuthorizationManager implements AuthorizationMan
Assert.notNull(expressionHandler, "expressionHandler cannot be null");
this.expressionHandler = expressionHandler;
this.expression = expressionHandler.getExpressionParser()
.parseExpression(this.expression.getExpressionString());
.parseExpression(this.expression.getExpressionString());
}
/**
@@ -53,7 +53,7 @@ public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation>
WebExpressionConfigAttribute webExpressionConfigAttribute = findConfigAttribute(attributes);
if (webExpressionConfigAttribute == null) {
this.logger
.trace("Abstained since did not find a config attribute of instance WebExpressionConfigAttribute");
.trace("Abstained since did not find a config attribute of instance WebExpressionConfigAttribute");
return ACCESS_ABSTAIN;
}
EvaluationContext ctx = webExpressionConfigAttribute.postProcess(
@@ -51,7 +51,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class AuthorizationFilter extends GenericFilterBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private final AuthorizationManager<HttpServletRequest> authorizationManager;
@@ -31,7 +31,8 @@ class WebMvcSecurityRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(WebSecurityExpressionRoot.class, (builder) -> builder
hints.reflection()
.registerType(WebSecurityExpressionRoot.class, (builder) -> builder
.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS));
}
@@ -116,7 +116,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
implements ApplicationEventPublisherAware, MessageSourceAware {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
protected ApplicationEventPublisher eventPublisher;
@@ -268,7 +268,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
}
if (this.logger.isTraceEnabled()) {
this.logger
.trace(LogMessage.format("Did not match request to %s", this.requiresAuthenticationRequestMatcher));
.trace(LogMessage.format("Did not match request to %s", this.requiresAuthenticationRequestMatcher));
}
return false;
}
@@ -51,7 +51,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
@@ -96,7 +96,7 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
throws IOException, ServletException {
Supplier<SecurityContext> deferredContext = this.securityContextHolderStrategy.getDeferredContext();
this.securityContextHolderStrategy
.setDeferredContext(defaultWithAnonymous((HttpServletRequest) req, deferredContext));
.setDeferredContext(defaultWithAnonymous((HttpServletRequest) req, deferredContext));
chain.doFilter(req, res);
}
@@ -69,7 +69,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
public class AuthenticationFilter extends OncePerRequestFilter {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private RequestMatcher requestMatcher = AnyRequestMatcher.INSTANCE;
@@ -66,7 +66,7 @@ public class DelegatingAuthenticationFailureHandler implements AuthenticationFai
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
for (Map.Entry<Class<? extends AuthenticationException>, AuthenticationFailureHandler> entry : this.handlers
.entrySet()) {
.entrySet()) {
Class<? extends AuthenticationException> handlerMappedExceptionClass = entry.getKey();
if (handlerMappedExceptionClass.isAssignableFrom(exception.getClass())) {
AuthenticationFailureHandler handler = entry.getValue();
@@ -54,7 +54,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class LogoutFilter extends GenericFilterBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private RequestMatcher logoutRequestMatcher;
@@ -49,7 +49,7 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private boolean invalidateHttpSession = true;
@@ -90,7 +90,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
implements ApplicationEventPublisherAware {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private ApplicationEventPublisher eventPublisher = null;
@@ -136,8 +136,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
throws IOException, ServletException {
if (this.requiresAuthenticationRequestMatcher.matches((HttpServletRequest) request)) {
if (logger.isDebugEnabled()) {
logger.debug(LogMessage.of(
() -> "Authenticating " + this.securityContextHolderStrategy.getContext().getAuthentication()));
logger.debug(LogMessage
.of(() -> "Authenticating " + this.securityContextHolderStrategy.getContext().getAuthentication()));
}
doAuthenticate((HttpServletRequest) request, (HttpServletResponse) response);
}
@@ -370,7 +370,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
@Override
public boolean matches(HttpServletRequest request) {
Authentication currentUser = AbstractPreAuthenticatedProcessingFilter.this.securityContextHolderStrategy
.getContext().getAuthentication();
.getContext()
.getAuthentication();
if (currentUser == null) {
return true;
}
@@ -381,7 +382,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
return false;
}
AbstractPreAuthenticatedProcessingFilter.this.logger
.debug("Pre-authenticated principal has changed and will be reauthenticated");
.debug("Pre-authenticated principal has changed and will be reauthenticated");
if (AbstractPreAuthenticatedProcessingFilter.this.invalidateSessionOnPrincipalChange) {
AbstractPreAuthenticatedProcessingFilter.this.securityContextHolderStrategy.clearContext();
HttpSession session = request.getSession(false);
@@ -94,7 +94,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
return null;
}
UserDetails userDetails = this.preAuthenticatedUserDetailsService
.loadUserDetails((PreAuthenticatedAuthenticationToken) authentication);
.loadUserDetails((PreAuthenticatedAuthenticationToken) authentication);
this.userDetailsChecker.check(userDetails);
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(userDetails,
authentication.getCredentials(), userDetails.getAuthorities());
@@ -58,7 +58,7 @@ public class PreAuthenticatedGrantedAuthoritiesUserDetailsService
Assert.notNull(token.getDetails(), "token.getDetails() cannot be null");
Assert.isInstanceOf(GrantedAuthoritiesContainer.class, token.getDetails());
Collection<? extends GrantedAuthority> authorities = ((GrantedAuthoritiesContainer) token.getDetails())
.getGrantedAuthorities();
.getGrantedAuthorities();
return createUserDetails(token, authorities);
}
@@ -93,7 +93,7 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource implements
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails buildDetails(HttpServletRequest context) {
Collection<String> j2eeUserRoles = getUserRoles(context);
Collection<? extends GrantedAuthority> userGrantedAuthorities = this.j2eeUserRoles2GrantedAuthoritiesMapper
.getGrantedAuthorities(j2eeUserRoles);
.getGrantedAuthorities(j2eeUserRoles);
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("J2EE roles [%s] mapped to Granted Authorities: [%s]", j2eeUserRoles,
userGrantedAuthorities));
@@ -67,7 +67,7 @@ public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource implements
private Collection<? extends GrantedAuthority> getWebSphereGroupsBasedGrantedAuthorities() {
List<String> webSphereGroups = this.wasHelper.getGroupsForCurrentUser();
Collection<? extends GrantedAuthority> userGas = this.webSphereGroups2GrantedAuthoritiesMapper
.getGrantedAuthorities(webSphereGroups);
.getGrantedAuthorities(webSphereGroups);
this.logger.debug(
LogMessage.format("WebSphere groups: %s mapped to Granted Authorities: %s", webSphereGroups, userGas));
return userGas;
@@ -388,7 +388,7 @@ public abstract class AbstractRememberMeServices
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
this.logger.debug(LogMessage
.of(() -> "Logout of user " + ((authentication != null) ? authentication.getName() : "Unknown")));
.of(() -> "Logout of user " + ((authentication != null) ? authentication.getName() : "Unknown")));
cancelCookie(request, response);
}
@@ -69,7 +69,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class RememberMeAuthenticationFilter extends GenericFilterBean implements ApplicationEventPublisherAware {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private ApplicationEventPublisher eventPublisher;
@@ -105,8 +105,8 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
throws IOException, ServletException {
if (this.securityContextHolderStrategy.getContext().getAuthentication() != null) {
this.logger.debug(LogMessage
.of(() -> "SecurityContextHolder not populated with remember-me token, as it already contained: '"
+ this.securityContextHolderStrategy.getContext().getAuthentication() + "'"));
.of(() -> "SecurityContextHolder not populated with remember-me token, as it already contained: '"
+ this.securityContextHolderStrategy.getContext().getAuthentication() + "'"));
chain.doFilter(request, response);
return;
}
@@ -134,9 +134,9 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
}
catch (AuthenticationException ex) {
this.logger.debug(LogMessage
.format("SecurityContextHolder not populated with remember-me token, as AuthenticationManager "
+ "rejected Authentication returned by RememberMeServices: '%s'; "
+ "invalidating remember-me token", rememberMeAuth),
.format("SecurityContextHolder not populated with remember-me token, as AuthenticationManager "
+ "rejected Authentication returned by RememberMeServices: '%s'; "
+ "invalidating remember-me token", rememberMeAuth),
ex);
this.rememberMeServices.loginFail(request, response);
onUnsuccessfulAuthentication(request, response, ex);
@@ -238,8 +238,8 @@ public class TokenBasedRememberMeServices extends AbstractRememberMeServices {
setCookie(new String[] { username, Long.toString(expiryTime), this.encodingAlgorithm.name(), signatureValue },
tokenLifetime, request, response);
if (this.logger.isDebugEnabled()) {
this.logger.debug(
"Added remember-me cookie for user '" + username + "', expiry: '" + new Date(expiryTime) + "'");
this.logger
.debug("Added remember-me cookie for user '" + username + "', expiry: '" + new Date(expiryTime) + "'");
}
}
@@ -126,7 +126,7 @@ public abstract class AbstractSessionFixationProtectionStrategy
*/
protected void onSessionChange(String originalSessionId, HttpSession newSession, Authentication auth) {
this.applicationEventPublisher
.publishEvent(new SessionFixationProtectionEvent(auth, originalSessionId, newSession.getId()));
.publishEvent(new SessionFixationProtectionEvent(auth, originalSessionId, newSession.getId()));
}
/**
@@ -119,7 +119,7 @@ public class SwitchUserFilter extends GenericFilterBean implements ApplicationEv
public static final String ROLE_PREVIOUS_ADMINISTRATOR = "ROLE_PREVIOUS_ADMINISTRATOR";
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private ApplicationEventPublisher eventPublisher;
@@ -258,7 +258,7 @@ public class SwitchUserFilter extends GenericFilterBean implements ApplicationEv
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
if (current == null) {
throw new AuthenticationCredentialsNotFoundException(this.messages
.getMessage("SwitchUserFilter.noCurrentUser", "No current user associated with this request"));
.getMessage("SwitchUserFilter.noCurrentUser", "No current user associated with this request"));
}
// check to see if the current user did actual switch to another user
// if so, get the original source user so we can switch back
@@ -266,7 +266,7 @@ public class SwitchUserFilter extends GenericFilterBean implements ApplicationEv
if (original == null) {
this.logger.debug("Failed to find original user");
throw new AuthenticationCredentialsNotFoundException(this.messages
.getMessage("SwitchUserFilter.noOriginalAuthentication", "Failed to find original user"));
.getMessage("SwitchUserFilter.noOriginalAuthentication", "Failed to find original user"));
}
// get the source user details
UserDetails originalUser = null;
@@ -231,7 +231,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
sb.append(createLogoutSuccess(logoutSuccess));
sb.append("<table class=\"table table-striped\">\n");
for (Map.Entry<String, String> clientAuthenticationUrlToClientName : this.oauth2AuthenticationUrlToClientName
.entrySet()) {
.entrySet()) {
sb.append(" <tr><td>");
String url = clientAuthenticationUrlToClientName.getKey();
sb.append("<a href=\"").append(contextPath).append(url).append("\">");
@@ -248,7 +248,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
sb.append(createLogoutSuccess(logoutSuccess));
sb.append("<table class=\"table table-striped\">\n");
for (Map.Entry<String, String> relyingPartyUrlToName : this.saml2AuthenticationUrlToProviderName
.entrySet()) {
.entrySet()) {
sb.append(" <tr><td>");
String url = relyingPartyUrlToName.getKey();
sb.append("<a href=\"").append(contextPath).append(url).append("\">");
@@ -266,8 +266,8 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
private String getLoginErrorMessage(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null &&
session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION) instanceof AuthenticationException exception) {
if (session != null && session
.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION) instanceof AuthenticationException exception) {
return exception.getMessage();
}
return "Invalid credentials";
@@ -95,7 +95,7 @@ public class BasicAuthenticationConverter implements AuthenticationConverter {
throw new BadCredentialsException("Invalid basic authentication token");
}
UsernamePasswordAuthenticationToken result = UsernamePasswordAuthenticationToken
.unauthenticated(token.substring(0, delim), token.substring(delim + 1));
.unauthenticated(token.substring(0, delim), token.substring(delim + 1));
result.setDetails(this.authenticationDetailsSource.buildDetails(request));
return result;
}
@@ -93,7 +93,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
public class BasicAuthenticationFilter extends OncePerRequestFilter {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private AuthenticationEntryPoint authenticationEntryPoint;
@@ -95,7 +95,7 @@ public class DigestAuthenticationFilter extends GenericFilterBean implements Mes
private static final Log logger = LogFactory.getLog(DigestAuthenticationFilter.class);
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
@@ -29,9 +29,9 @@ import org.springframework.security.core.Authentication;
* {@link Authentication#getPrincipal()}. This is necessary to signal that the argument
* should be resolved to the current user rather than a user that might be edited on a
* form.
*
* @deprecated Use
* {@link org.springframework.security.core.annotation.AuthenticationPrincipal} instead.
*
* @author Rob Winch
* @since 3.2
*/
@@ -93,7 +93,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
protected final Log logger = LogFactory.getLog(this.getClass());
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
/**
* SecurityContext instance used to check for equality with default (unauthenticated)
@@ -227,8 +227,8 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
}
if (this.logger.isTraceEnabled()) {
this.logger.trace(
LogMessage.format("Retrieved %s from %s", contextFromSession, this.springSecurityContextKey));
this.logger
.trace(LogMessage.format("Retrieved %s from %s", contextFromSession, this.springSecurityContextKey));
}
else if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Retrieved %s", contextFromSession));
@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
public final class NullSecurityContextRepository implements SecurityContextRepository {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
@Override
public boolean containsContext(HttpServletRequest request) {
@@ -47,12 +47,12 @@ public final class RequestAttributeSecurityContextRepository implements Security
* The default request attribute name to use.
*/
public static final String DEFAULT_REQUEST_ATTR_NAME = RequestAttributeSecurityContextRepository.class.getName()
.concat(".SPRING_SECURITY_CONTEXT");
.concat(".SPRING_SECURITY_CONTEXT");
private final String requestAttributeName;
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
/**
* Creates a new instance using {@link #DEFAULT_REQUEST_ATTR_NAME}.
@@ -49,7 +49,7 @@ import org.springframework.util.Assert;
public abstract class SaveContextOnUpdateOrErrorResponseWrapper extends OnCommittedResponseWrapper {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private boolean contextSaved = false;
@@ -52,7 +52,7 @@ public class SecurityContextHolderFilter extends GenericFilterBean {
private final SecurityContextRepository securityContextRepository;
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
/**
* Creates a new instance.
@@ -69,7 +69,7 @@ public class SecurityContextPersistenceFilter extends GenericFilterBean {
private SecurityContextRepository repo;
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private boolean forceEagerSessionCreation = false;
@@ -111,7 +111,7 @@ public class SecurityContextPersistenceFilter extends GenericFilterBean {
else {
if (this.logger.isDebugEnabled()) {
this.logger
.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));
.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));
}
}
chain.doFilter(holder.getRequest(), holder.getResponse());
@@ -45,7 +45,7 @@ public final class SecurityContextCallableProcessingInterceptor implements Calla
private volatile SecurityContext securityContext;
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
/**
* Create a new {@link SecurityContextCallableProcessingInterceptor} that uses the
@@ -46,14 +46,14 @@ public final class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter
private static final Object CALLABLE_INTERCEPTOR_KEY = new Object();
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor) asyncManager
.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
if (securityProcessingInterceptor == null) {
SecurityContextCallableProcessingInterceptor interceptor = new SecurityContextCallableProcessingInterceptor();
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
@@ -48,7 +48,7 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
static final String DEFAULT_CSRF_HEADER_NAME = "X-XSRF-TOKEN";
private static final String CSRF_TOKEN_REMOVED_ATTRIBUTE_NAME = CookieCsrfTokenRepository.class.getName()
.concat(".REMOVED");
.concat(".REMOVED");
private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;
@@ -90,10 +90,11 @@ public final class CookieCsrfTokenRepository implements CsrfTokenRepository {
String tokenValue = (token != null) ? token.getToken() : "";
ResponseCookie.ResponseCookieBuilder cookieBuilder = ResponseCookie.from(this.cookieName, tokenValue)
.secure((this.secure != null) ? this.secure : request.isSecure())
.path(StringUtils.hasLength(this.cookiePath) ? this.cookiePath : this.getRequestContext(request))
.maxAge((token != null) ? this.cookieMaxAge : 0).httpOnly(this.cookieHttpOnly)
.domain(this.cookieDomain);
.secure((this.secure != null) ? this.secure : request.isSecure())
.path(StringUtils.hasLength(this.cookiePath) ? this.cookiePath : this.getRequestContext(request))
.maxAge((token != null) ? this.cookieMaxAge : 0)
.httpOnly(this.cookieHttpOnly)
.domain(this.cookieDomain);
this.cookieCustomizer.accept(cookieBuilder);
@@ -121,8 +121,8 @@ public final class CsrfFilter extends OncePerRequestFilter {
String actualToken = this.requestHandler.resolveCsrfTokenValue(request, csrfToken);
if (!equalsConstantTime(csrfToken.getToken(), actualToken)) {
boolean missingToken = deferredCsrfToken.isGenerated();
this.logger.debug(
LogMessage.of(() -> "Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)));
this.logger
.debug(LogMessage.of(() -> "Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)));
AccessDeniedException exception = (!missingToken) ? new InvalidCsrfTokenException(csrfToken, actualToken)
: new MissingCsrfTokenException(actualToken);
this.accessDeniedHandler.handle(request, response, exception);
@@ -38,7 +38,7 @@ public final class HttpSessionCsrfTokenRepository implements CsrfTokenRepository
private static final String DEFAULT_CSRF_HEADER_NAME = "X-CSRF-TOKEN";
private static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = HttpSessionCsrfTokenRepository.class.getName()
.concat(".CSRF_TOKEN");
.concat(".CSRF_TOKEN");
private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;
@@ -91,19 +91,19 @@ public class StrictHttpFirewall implements HttpFirewall {
private static final String PERCENT = "%";
private static final List<String> FORBIDDEN_ENCODED_PERIOD = Collections
.unmodifiableList(Arrays.asList("%2e", "%2E"));
.unmodifiableList(Arrays.asList("%2e", "%2E"));
private static final List<String> FORBIDDEN_SEMICOLON = Collections
.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
private static final List<String> FORBIDDEN_FORWARDSLASH = Collections
.unmodifiableList(Arrays.asList("%2f", "%2F"));
.unmodifiableList(Arrays.asList("%2f", "%2F"));
private static final List<String> FORBIDDEN_DOUBLE_FORWARDSLASH = Collections
.unmodifiableList(Arrays.asList("//", "%2f%2f", "%2f%2F", "%2F%2f", "%2F%2F"));
.unmodifiableList(Arrays.asList("//", "%2f%2f", "%2f%2F", "%2F%2f", "%2F%2F"));
private static final List<String> FORBIDDEN_BACKSLASH = Collections
.unmodifiableList(Arrays.asList("\\", "%5c", "%5C"));
.unmodifiableList(Arrays.asList("\\", "%5c", "%5C"));
private static final List<String> FORBIDDEN_NULL = Collections.unmodifiableList(Arrays.asList("\0", "%00"));
@@ -114,7 +114,7 @@ public class StrictHttpFirewall implements HttpFirewall {
private static final List<String> FORBIDDEN_LINE_SEPARATOR = Collections.unmodifiableList(Arrays.asList("\u2028"));
private static final List<String> FORBIDDEN_PARAGRAPH_SEPARATOR = Collections
.unmodifiableList(Arrays.asList("\u2029"));
.unmodifiableList(Arrays.asList("\u2029"));
private Set<String> encodedUrlBlocklist = new HashSet<>();
@@ -125,7 +125,7 @@ public class StrictHttpFirewall implements HttpFirewall {
private Predicate<String> allowedHostnames = (hostname) -> true;
private static final Pattern ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN = Pattern
.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*");
.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*");
private static final Predicate<String> ASSIGNED_AND_NOT_ISO_CONTROL_PREDICATE = (
s) -> ASSIGNED_AND_NOT_ISO_CONTROL_PATTERN.matcher(s).matches();
@@ -513,8 +513,8 @@ public class StrictHttpFirewall implements HttpFirewall {
private void rejectNonPrintableAsciiCharactersInFieldName(String toCheck, String propertyName) {
if (!containsOnlyPrintableAsciiCharacters(toCheck)) {
throw new RequestRejectedException(String.format(
"The %s was rejected because it can only contain printable ASCII characters.", propertyName));
throw new RequestRejectedException(String
.format("The %s was rejected because it can only contain printable ASCII characters.", propertyName));
}
}
@@ -55,7 +55,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class JaasApiIntegrationFilter extends GenericFilterBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private boolean createEmptySubject;
@@ -91,7 +91,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
public final class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private ExpressionParser parser = new SpelExpressionParser();
@@ -77,7 +77,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
public final class CurrentSecurityContextArgumentResolver implements HandlerMethodArgumentResolver {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private ExpressionParser parser = new SpelExpressionParser();
@@ -73,12 +73,12 @@ public class AuthenticationPrincipalArgumentResolver extends HandlerMethodArgume
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
return ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication)
.flatMap((authentication) -> {
Mono<Object> principal = Mono
.justOrEmpty(resolvePrincipal(parameter, authentication.getPrincipal()));
return (adapter != null) ? Mono.just(adapter.fromPublisher(principal)) : principal;
});
return ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.flatMap((authentication) -> {
Mono<Object> principal = Mono.justOrEmpty(resolvePrincipal(parameter, authentication.getPrincipal()));
return (adapter != null) ? Mono.just(adapter.fromPublisher(principal)) : principal;
});
}
private Object resolvePrincipal(MethodParameter parameter, Object principal) {
@@ -76,9 +76,14 @@ public class CookieRequestCache implements RequestCache {
UriComponents uriComponents = UriComponentsBuilder.fromUriString(originalURI).build();
DefaultSavedRequest.Builder builder = new DefaultSavedRequest.Builder();
int port = getPort(uriComponents);
return builder.setScheme(uriComponents.getScheme()).setServerName(uriComponents.getHost())
.setRequestURI(uriComponents.getPath()).setQueryString(uriComponents.getQuery()).setServerPort(port)
.setMethod(request.getMethod()).setLocales(Collections.list(request.getLocales())).build();
return builder.setScheme(uriComponents.getScheme())
.setServerName(uriComponents.getHost())
.setRequestURI(uriComponents.getPath())
.setQueryString(uriComponents.getQuery())
.setServerPort(port)
.setMethod(request.getMethod())
.setLocales(Collections.list(request.getLocales()))
.build();
}
private int getPort(UriComponents uriComponents) {
@@ -372,8 +372,12 @@ public class DefaultSavedRequest implements SavedRequest {
if (queryString == null || queryString.length() == 0) {
return matchingRequestParameterName;
}
return UriComponentsBuilder.newInstance().query(queryString).replaceQueryParam(matchingRequestParameterName)
.queryParam(matchingRequestParameterName).build().getQuery();
return UriComponentsBuilder.newInstance()
.query(queryString)
.replaceQueryParam(matchingRequestParameterName)
.queryParam(matchingRequestParameterName)
.build()
.getQuery();
}
/**
@@ -63,8 +63,8 @@ public class HttpSessionRequestCache implements RequestCache {
public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
if (!this.requestMatcher.matches(request)) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(
LogMessage.format("Did not save request since it did not match [%s]", this.requestMatcher));
this.logger
.trace(LogMessage.format("Did not save request since it did not match [%s]", this.requestMatcher));
}
return;
}
@@ -104,8 +104,10 @@ public class HttpSessionRequestCache implements RequestCache {
public HttpServletRequest getMatchingRequest(HttpServletRequest request, HttpServletResponse response) {
if (this.matchingRequestParameterName != null) {
if (!StringUtils.hasText(request.getQueryString())
|| !UriComponentsBuilder.fromUriString(UrlUtils.buildRequestUrl(request)).build().getQueryParams()
.containsKey(this.matchingRequestParameterName)) {
|| !UriComponentsBuilder.fromUriString(UrlUtils.buildRequestUrl(request))
.build()
.getQueryParams()
.containsKey(this.matchingRequestParameterName)) {
this.logger.trace(
"matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided");
return null;
@@ -62,13 +62,15 @@ public class DelegatingServerAuthenticationEntryPoint implements ServerAuthentic
@Override
public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
return Flux.fromIterable(this.entryPoints).filterWhen((entry) -> isMatch(exchange, entry)).next()
.map((entry) -> entry.getEntryPoint())
.doOnNext((entryPoint) -> logger.debug(LogMessage.format("Match found! Executing %s", entryPoint)))
.switchIfEmpty(Mono.just(this.defaultEntryPoint)
.doOnNext((entryPoint) -> logger.debug(LogMessage
.format("No match found. Using default entry point %s", this.defaultEntryPoint))))
.flatMap((entryPoint) -> entryPoint.commence(exchange, ex));
return Flux.fromIterable(this.entryPoints)
.filterWhen((entry) -> isMatch(exchange, entry))
.next()
.map((entry) -> entry.getEntryPoint())
.doOnNext((entryPoint) -> logger.debug(LogMessage.format("Match found! Executing %s", entryPoint)))
.switchIfEmpty(Mono.just(this.defaultEntryPoint)
.doOnNext((entryPoint) -> logger
.debug(LogMessage.format("No match found. Using default entry point %s", this.defaultEntryPoint))))
.flatMap((entryPoint) -> entryPoint.commence(exchange, ex));
}
private Mono<Boolean> isMatch(ServerWebExchange exchange, DelegateEntry entry) {
@@ -81,7 +81,8 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
AroundWebFilterObservation parent = observation(exchange);
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
Observation observation = Observation.createNotStarted(SECURED_OBSERVATION_NAME, this.registry)
.contextualName("secured request").parentObservation(parentObservation);
.contextualName("secured request")
.parentObservation(parentObservation);
return parent.wrap(WebFilterObservation.create(observation).wrap(original)).filter(exchange);
});
}
@@ -90,7 +91,8 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
return (exchange) -> Mono.deferContextual((contextView) -> {
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
Observation observation = Observation.createNotStarted(UNSECURED_OBSERVATION_NAME, this.registry)
.contextualName("unsecured request").parentObservation(parentObservation);
.contextualName("unsecured request")
.parentObservation(parentObservation);
return WebFilterObservation.create(observation).wrap(original).filter(exchange);
});
}
@@ -224,9 +226,9 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
WebFilterChainObservationContext beforeContext = WebFilterChainObservationContext.before();
WebFilterChainObservationContext afterContext = WebFilterChainObservationContext.after();
Observation before = Observation.createNotStarted(this.convention, () -> beforeContext, this.registry)
.parentObservation(parentObservation);
.parentObservation(parentObservation);
Observation after = Observation.createNotStarted(this.convention, () -> afterContext, this.registry)
.parentObservation(parentObservation);
.parentObservation(parentObservation);
AroundWebFilterObservation parent = AroundWebFilterObservation.create(before, after);
exchange.getAttributes().put(ATTRIBUTE, parent);
return parent;
@@ -582,11 +584,13 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
}
return (exchange, chain) -> {
this.observation.start();
return filter.filter(exchange, chain).doOnSuccess((v) -> this.observation.stop())
.doOnCancel(this.observation::stop).doOnError((t) -> {
this.observation.error(t);
this.observation.stop();
});
return filter.filter(exchange, chain)
.doOnSuccess((v) -> this.observation.stop())
.doOnCancel(this.observation::stop)
.doOnError((t) -> {
this.observation.error(t);
this.observation.stop();
});
};
}
@@ -597,12 +601,14 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
}
return (exchange) -> {
this.observation.start();
return chain.filter(exchange).doOnSuccess((v) -> this.observation.stop())
.doOnCancel(this.observation::stop).doOnError((t) -> {
this.observation.error(t);
this.observation.stop();
}).contextWrite(
(context) -> context.put(ObservationThreadLocalAccessor.KEY, this.observation));
return chain.filter(exchange)
.doOnSuccess((v) -> this.observation.stop())
.doOnCancel(this.observation::stop)
.doOnError((t) -> {
this.observation.error(t);
this.observation.stop();
})
.contextWrite((context) -> context.put(ObservationThreadLocalAccessor.KEY, this.observation));
};
}
@@ -688,10 +694,10 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
@Override
public KeyValues getLowCardinalityKeyValues(WebFilterChainObservationContext context) {
return KeyValues.of(CHAIN_SIZE_NAME, String.valueOf(context.getChainSize()))
.and(CHAIN_POSITION_NAME, String.valueOf(context.getChainPosition()))
.and(FILTER_SECTION_NAME, context.getFilterSection())
.and(FILTER_NAME, (StringUtils.hasText(context.getFilterName())) ? context.getFilterName()
: KeyValue.NONE_VALUE);
.and(CHAIN_POSITION_NAME, String.valueOf(context.getChainPosition()))
.and(FILTER_SECTION_NAME, context.getFilterSection())
.and(FILTER_NAME,
(StringUtils.hasText(context.getFilterName())) ? context.getFilterName() : KeyValue.NONE_VALUE);
}
@Override
@@ -54,12 +54,13 @@ public class WebFilterChainProxy implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return Flux.fromIterable(this.filters)
.filterWhen((securityWebFilterChain) -> securityWebFilterChain.matches(exchange)).next()
.switchIfEmpty(
Mono.defer(() -> this.filterChainDecorator.decorate(chain).filter(exchange).then(Mono.empty())))
.flatMap((securityWebFilterChain) -> securityWebFilterChain.getWebFilters().collectList())
.map((filters) -> this.filterChainDecorator.decorate(chain, filters))
.flatMap((securedChain) -> securedChain.filter(exchange));
.filterWhen((securityWebFilterChain) -> securityWebFilterChain.matches(exchange))
.next()
.switchIfEmpty(
Mono.defer(() -> this.filterChainDecorator.decorate(chain).filter(exchange).then(Mono.empty())))
.flatMap((securityWebFilterChain) -> securityWebFilterChain.getWebFilters().collectList())
.map((filters) -> this.filterChainDecorator.decorate(chain, filters))
.flatMap((securedChain) -> securedChain.filter(exchange));
}
/**
@@ -83,8 +83,8 @@ public class AnonymousAuthenticationWebFilter implements WebFilter {
SecurityContext securityContext = new SecurityContextImpl(authentication);
logger.debug(LogMessage.format("Populated SecurityContext with anonymous token: '%s'", authentication));
return chain.filter(exchange)
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)))
.then(Mono.empty());
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)))
.then(Mono.empty());
})).flatMap((securityContext) -> {
logger.debug(LogMessage.format("SecurityContext contains anonymous token: '%s'",
securityContext.getAuthentication()));
@@ -43,8 +43,10 @@ public final class AuthenticationConverterServerWebExchangeMatcher implements Se
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
return this.serverAuthenticationConverter.convert(exchange).flatMap((a) -> MatchResult.match())
.onErrorResume((ex) -> MatchResult.notMatch()).switchIfEmpty(MatchResult.notMatch());
return this.serverAuthenticationConverter.convert(exchange)
.flatMap((a) -> MatchResult.match())
.onErrorResume((ex) -> MatchResult.notMatch())
.switchIfEmpty(MatchResult.notMatch());
}
}
@@ -82,7 +82,7 @@ public class AuthenticationWebFilter implements WebFilter {
new HttpBasicServerAuthenticationEntryPoint());
private ServerSecurityContextRepository securityContextRepository = NoOpServerSecurityContextRepository
.getInstance();
.getInstance();
private ServerWebExchangeMatcher requiresAuthenticationMatcher = ServerWebExchangeMatchers.anyExchange();
@@ -108,23 +108,24 @@ public class AuthenticationWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.requiresAuthenticationMatcher.matches(exchange).filter((matchResult) -> matchResult.isMatch())
.flatMap((matchResult) -> this.authenticationConverter.convert(exchange))
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((token) -> authenticate(exchange, chain, token))
.onErrorResume(AuthenticationException.class, (ex) -> this.authenticationFailureHandler
.onAuthenticationFailure(new WebFilterExchange(exchange, chain), ex));
return this.requiresAuthenticationMatcher.matches(exchange)
.filter((matchResult) -> matchResult.isMatch())
.flatMap((matchResult) -> this.authenticationConverter.convert(exchange))
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((token) -> authenticate(exchange, chain, token))
.onErrorResume(AuthenticationException.class, (ex) -> this.authenticationFailureHandler
.onAuthenticationFailure(new WebFilterExchange(exchange, chain), ex));
}
private Mono<Void> authenticate(ServerWebExchange exchange, WebFilterChain chain, Authentication token) {
return this.authenticationManagerResolver.resolve(exchange)
.flatMap((authenticationManager) -> authenticationManager.authenticate(token))
.switchIfEmpty(Mono.defer(
() -> Mono.error(new IllegalStateException("No provider found for " + token.getClass()))))
.flatMap((authentication) -> onAuthenticationSuccess(authentication,
new WebFilterExchange(exchange, chain)))
.doOnError(AuthenticationException.class,
(ex) -> logger.debug(LogMessage.format("Authentication failed: %s", ex.getMessage())));
.flatMap((authenticationManager) -> authenticationManager.authenticate(token))
.switchIfEmpty(Mono
.defer(() -> Mono.error(new IllegalStateException("No provider found for " + token.getClass()))))
.flatMap(
(authentication) -> onAuthenticationSuccess(authentication, new WebFilterExchange(exchange, chain)))
.doOnError(AuthenticationException.class,
(ex) -> logger.debug(LogMessage.format("Authentication failed: %s", ex.getMessage())));
}
protected Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) {
@@ -132,8 +133,8 @@ public class AuthenticationWebFilter implements WebFilter {
SecurityContextImpl securityContext = new SecurityContextImpl();
securityContext.setAuthentication(authentication);
return this.securityContextRepository.save(exchange, securityContext)
.then(this.authenticationSuccessHandler.onAuthenticationSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)));
.then(this.authenticationSuccessHandler.onAuthenticationSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)));
}
/**
@@ -45,7 +45,8 @@ public class DelegatingServerAuthenticationSuccessHandler implements ServerAuthe
@Override
public Mono<Void> onAuthenticationSuccess(WebFilterExchange exchange, Authentication authentication) {
return Flux.fromIterable(this.delegates)
.concatMap((delegate) -> delegate.onAuthenticationSuccess(exchange, authentication)).then();
.concatMap((delegate) -> delegate.onAuthenticationSuccess(exchange, authentication))
.then();
}
}
@@ -58,15 +58,18 @@ public class ReactivePreAuthenticatedAuthenticationManager implements ReactiveAu
@Override
public Mono<Authentication> authenticate(Authentication authentication) {
return Mono.just(authentication).filter(this::supports).map(Authentication::getName)
.flatMap(this.userDetailsService::findByUsername)
.switchIfEmpty(Mono.error(() -> new UsernameNotFoundException("User not found")))
.doOnNext(this.userDetailsChecker::check).map((userDetails) -> {
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(userDetails,
authentication.getCredentials(), userDetails.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
});
return Mono.just(authentication)
.filter(this::supports)
.map(Authentication::getName)
.flatMap(this.userDetailsService::findByUsername)
.switchIfEmpty(Mono.error(() -> new UsernameNotFoundException("User not found")))
.doOnNext(this.userDetailsChecker::check)
.map((userDetails) -> {
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(userDetails,
authentication.getCredentials(), userDetails.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
});
}
private boolean supports(Authentication authentication) {
@@ -64,7 +64,7 @@ public class RedirectServerAuthenticationEntryPoint implements ServerAuthenticat
@Override
public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
return this.requestCache.saveRequest(exchange)
.then(this.redirectStrategy.sendRedirect(exchange, this.location));
.then(this.redirectStrategy.sendRedirect(exchange, this.location));
}
/**
@@ -72,8 +72,9 @@ public class RedirectServerAuthenticationSuccessHandler implements ServerAuthent
@Override
public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
ServerWebExchange exchange = webFilterExchange.getExchange();
return this.requestCache.getRedirectUri(exchange).defaultIfEmpty(this.location)
.flatMap((location) -> this.redirectStrategy.sendRedirect(exchange, location));
return this.requestCache.getRedirectUri(exchange)
.defaultIfEmpty(this.location)
.flatMap((location) -> this.redirectStrategy.sendRedirect(exchange, location));
}
/**
@@ -48,7 +48,7 @@ public final class ServerWebExchangeDelegatingReactiveAuthenticationManagerResol
private final List<ServerWebExchangeMatcherEntry<ReactiveAuthenticationManager>> authenticationManagers;
private ReactiveAuthenticationManager defaultAuthenticationManager = (authentication) -> Mono
.error(new AuthenticationServiceException("Cannot authenticate " + authentication));
.error(new AuthenticationServiceException("Cannot authenticate " + authentication));
/**
* Construct an
@@ -78,8 +78,11 @@ public final class ServerWebExchangeDelegatingReactiveAuthenticationManagerResol
*/
@Override
public Mono<ReactiveAuthenticationManager> resolve(ServerWebExchange exchange) {
return Flux.fromIterable(this.authenticationManagers).filterWhen((entry) -> isMatch(exchange, entry)).next()
.map(ServerWebExchangeMatcherEntry::getEntry).defaultIfEmpty(this.defaultAuthenticationManager);
return Flux.fromIterable(this.authenticationManagers)
.filterWhen((entry) -> isMatch(exchange, entry))
.next()
.map(ServerWebExchangeMatcherEntry::getEntry)
.defaultIfEmpty(this.defaultAuthenticationManager);
}
/**
@@ -158,13 +158,14 @@ public class SwitchUserWebFilter implements WebFilter {
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
final WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain);
return switchUser(webFilterExchange).switchIfEmpty(Mono.defer(() -> exitSwitchUser(webFilterExchange)))
.switchIfEmpty(Mono.defer(() -> {
this.logger.trace(
LogMessage.format("Did not attempt to switch user since request did not match [%s] or [%s]",
this.switchUserMatcher, this.exitUserMatcher));
return chain.filter(exchange).then(Mono.empty());
})).flatMap((authentication) -> onAuthenticationSuccess(authentication, webFilterExchange))
.onErrorResume(SwitchUserAuthenticationException.class, (exception) -> Mono.empty());
.switchIfEmpty(Mono.defer(() -> {
this.logger
.trace(LogMessage.format("Did not attempt to switch user since request did not match [%s] or [%s]",
this.switchUserMatcher, this.exitUserMatcher));
return chain.filter(exchange).then(Mono.empty());
}))
.flatMap((authentication) -> onAuthenticationSuccess(authentication, webFilterExchange))
.onErrorResume(SwitchUserAuthenticationException.class, (exception) -> Mono.empty());
}
/**
@@ -177,13 +178,15 @@ public class SwitchUserWebFilter implements WebFilter {
*/
protected Mono<Authentication> switchUser(WebFilterExchange webFilterExchange) {
return this.switchUserMatcher.matches(webFilterExchange.getExchange())
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> ReactiveSecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication).flatMap((currentAuthentication) -> {
String username = getUsername(webFilterExchange.getExchange());
return attemptSwitchUser(currentAuthentication, username);
}).onErrorResume(AuthenticationException.class, (ex) -> onAuthenticationFailure(ex, webFilterExchange)
.then(Mono.error(new SwitchUserAuthenticationException(ex))));
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> ReactiveSecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.flatMap((currentAuthentication) -> {
String username = getUsername(webFilterExchange.getExchange());
return attemptSwitchUser(currentAuthentication, username);
})
.onErrorResume(AuthenticationException.class, (ex) -> onAuthenticationFailure(ex, webFilterExchange)
.then(Mono.error(new SwitchUserAuthenticationException(ex))));
}
/**
@@ -196,11 +199,11 @@ public class SwitchUserWebFilter implements WebFilter {
*/
protected Mono<Authentication> exitSwitchUser(WebFilterExchange webFilterExchange) {
return this.exitUserMatcher.matches(webFilterExchange.getExchange())
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.switchIfEmpty(Mono.error(this::noCurrentUserException)))
.map(this::attemptExitUser);
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.switchIfEmpty(Mono.error(this::noCurrentUserException)))
.map(this::attemptExitUser);
}
/**
@@ -217,9 +220,9 @@ public class SwitchUserWebFilter implements WebFilter {
Assert.notNull(userName, "The userName can not be null.");
this.logger.debug(LogMessage.format("Attempting to switch to user [%s]", userName));
return this.userDetailsService.findByUsername(userName)
.switchIfEmpty(Mono.error(this::noTargetAuthenticationException))
.doOnNext(this.userDetailsChecker::check)
.map((userDetails) -> createSwitchUserToken(userDetails, currentAuthentication));
.switchIfEmpty(Mono.error(this::noTargetAuthenticationException))
.doOnNext(this.userDetailsChecker::check)
.map((userDetails) -> createSwitchUserToken(userDetails, currentAuthentication));
}
@NonNull
@@ -236,9 +239,9 @@ public class SwitchUserWebFilter implements WebFilter {
ServerWebExchange exchange = webFilterExchange.getExchange();
SecurityContextImpl securityContext = new SecurityContextImpl(authentication);
return this.securityContextRepository.save(exchange, securityContext)
.doOnSuccess((v) -> this.logger.debug(LogMessage.format("Switched user to %s", authentication)))
.then(this.successHandler.onAuthenticationSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)));
.doOnSuccess((v) -> this.logger.debug(LogMessage.format("Switched user to %s", authentication)))
.then(this.successHandler.onAuthenticationSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)));
}
private Mono<Void> onAuthenticationFailure(AuthenticationException exception, WebFilterExchange webFilterExchange) {
@@ -50,8 +50,9 @@ public class DelegatingServerLogoutHandler implements ServerLogoutHandler {
@Override
public Mono<Void> logout(WebFilterExchange exchange, Authentication authentication) {
return Flux.fromIterable(this.delegates).concatMap((delegate) -> delegate.logout(exchange, authentication))
.then();
return Flux.fromIterable(this.delegates)
.concatMap((delegate) -> delegate.logout(exchange, authentication))
.then();
}
}
@@ -58,12 +58,15 @@ public class LogoutWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.requiresLogout.matches(exchange).filter((result) -> result.isMatch())
.switchIfEmpty(chain.filter(exchange).then(Mono.empty())).map((result) -> exchange)
.flatMap(this::flatMapAuthentication).flatMap((authentication) -> {
WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain);
return logout(webFilterExchange, authentication);
});
return this.requiresLogout.matches(exchange)
.filter((result) -> result.isMatch())
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.map((result) -> exchange)
.flatMap(this::flatMapAuthentication)
.flatMap((authentication) -> {
WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain);
return logout(webFilterExchange, authentication);
});
}
private Mono<Authentication> flatMapAuthentication(ServerWebExchange exchange) {
@@ -73,8 +76,8 @@ public class LogoutWebFilter implements WebFilter {
private Mono<Void> logout(WebFilterExchange webFilterExchange, Authentication authentication) {
logger.debug(LogMessage.format("Logging out user '%s' and transferring to logout destination", authentication));
return this.logoutHandler.logout(webFilterExchange, authentication)
.then(this.logoutSuccessHandler.onLogoutSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.clearContext());
.then(this.logoutSuccessHandler.onLogoutSuccess(webFilterExchange, authentication))
.contextWrite(ReactiveSecurityContextHolder.clearContext());
}
/**
@@ -46,13 +46,14 @@ public class AuthorizationWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return ReactiveSecurityContextHolder.getContext().filter((c) -> c.getAuthentication() != null)
.map(SecurityContext::getAuthentication)
.as((authentication) -> this.authorizationManager.verify(authentication, exchange))
.doOnSuccess((it) -> logger.debug("Authorization successful"))
.doOnError(AccessDeniedException.class,
(ex) -> logger.debug(LogMessage.format("Authorization failed: %s", ex.getMessage())))
.switchIfEmpty(chain.filter(exchange));
return ReactiveSecurityContextHolder.getContext()
.filter((c) -> c.getAuthentication() != null)
.map(SecurityContext::getAuthentication)
.as((authentication) -> this.authorizationManager.verify(authentication, exchange))
.doOnSuccess((it) -> logger.debug("Authorization successful"))
.doOnError(AccessDeniedException.class,
(ex) -> logger.debug(LogMessage.format("Authorization failed: %s", ex.getMessage())))
.switchIfEmpty(chain.filter(exchange));
}
}
@@ -50,13 +50,19 @@ public final class DelegatingReactiveAuthorizationManager implements ReactiveAut
@Override
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, ServerWebExchange exchange) {
return Flux.fromIterable(this.mappings).concatMap((mapping) -> mapping.getMatcher().matches(exchange)
.filter(MatchResult::isMatch).map(MatchResult::getVariables).flatMap((variables) -> {
return Flux.fromIterable(this.mappings)
.concatMap((mapping) -> mapping.getMatcher()
.matches(exchange)
.filter(MatchResult::isMatch)
.map(MatchResult::getVariables)
.flatMap((variables) -> {
logger.debug(LogMessage.of(() -> "Checking authorization on '"
+ exchange.getRequest().getPath().pathWithinApplication() + "' using "
+ mapping.getEntry()));
return mapping.getEntry().check(authentication, new AuthorizationContext(exchange, variables));
})).next().defaultIfEmpty(new AuthorizationDecision(false));
}))
.next()
.defaultIfEmpty(new AuthorizationDecision(false));
}
public static DelegatingReactiveAuthorizationManager.Builder builder() {
@@ -49,13 +49,15 @@ public class ExceptionTranslationWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).onErrorResume(AccessDeniedException.class, (denied) -> exchange.getPrincipal()
return chain.filter(exchange)
.onErrorResume(AccessDeniedException.class, (denied) -> exchange.getPrincipal()
.filter((principal) -> (!(principal instanceof Authentication) || (principal instanceof Authentication
&& !(this.authenticationTrustResolver.isAnonymous((Authentication) principal)))))
.switchIfEmpty(commenceAuthentication(exchange,
new InsufficientAuthenticationException(
"Full authentication is required to access this resource")))
.flatMap((principal) -> this.accessDeniedHandler.handle(exchange, denied)).then());
.flatMap((principal) -> this.accessDeniedHandler.handle(exchange, denied))
.then());
}
/**
@@ -92,8 +94,8 @@ public class ExceptionTranslationWebFilter implements WebFilter {
private <T> Mono<T> commenceAuthentication(ServerWebExchange exchange, AuthenticationException denied) {
return this.authenticationEntryPoint
.commence(exchange, new AuthenticationCredentialsNotFoundException("Not Authenticated", denied))
.then(Mono.empty());
.commence(exchange, new AuthenticationCredentialsNotFoundException("Not Authenticated", denied))
.then(Mono.empty());
}
}
@@ -41,8 +41,9 @@ public final class IpAddressReactiveAuthorizationManager implements ReactiveAuth
@Override
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext context) {
return Mono.just(context.getExchange()).flatMap(this.ipAddressExchangeMatcher::matches)
.map((matchResult) -> new AuthorizationDecision(matchResult.isMatch()));
return Mono.just(context.getExchange())
.flatMap(this.ipAddressExchangeMatcher::matches)
.map((matchResult) -> new AuthorizationDecision(matchResult.isMatch()));
}
/**
@@ -69,9 +69,12 @@ public class ServerWebExchangeDelegatingServerAccessDeniedHandler implements Ser
@Override
public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) {
return Flux.fromIterable(this.handlers).filterWhen((entry) -> isMatch(exchange, entry)).next()
.map(DelegateEntry::getAccessDeniedHandler).defaultIfEmpty(this.defaultHandler)
.flatMap((handler) -> handler.handle(exchange, denied));
return Flux.fromIterable(this.handlers)
.filterWhen((entry) -> isMatch(exchange, entry))
.next()
.map(DelegateEntry::getAccessDeniedHandler)
.defaultIfEmpty(this.defaultHandler)
.flatMap((handler) -> handler.handle(exchange, denied));
}
/**
@@ -44,13 +44,14 @@ public class ReactorContextWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).contextWrite(
(context) -> context.hasKey(SecurityContext.class) ? context : withSecurityContext(context, exchange));
return chain.filter(exchange)
.contextWrite((context) -> context.hasKey(SecurityContext.class) ? context
: withSecurityContext(context, exchange));
}
private Context withSecurityContext(Context mainContext, ServerWebExchange exchange) {
return mainContext.putAll(
this.repository.load(exchange).as(ReactiveSecurityContextHolder::withSecurityContext).readOnly());
return mainContext
.putAll(this.repository.load(exchange).as(ReactiveSecurityContextHolder::withSecurityContext).readOnly());
}
}
@@ -118,11 +118,13 @@ public class CsrfWebFilter implements WebFilter {
if (Boolean.TRUE.equals(exchange.getAttribute(SHOULD_NOT_FILTER))) {
return chain.filter(exchange).then(Mono.empty());
}
return this.requireCsrfProtectionMatcher.matches(exchange).filter(MatchResult::isMatch)
.filter((matchResult) -> !exchange.getAttributes().containsKey(CsrfToken.class.getName()))
.flatMap((m) -> validateToken(exchange)).flatMap((m) -> continueFilterChain(exchange, chain))
.switchIfEmpty(continueFilterChain(exchange, chain).then(Mono.empty()))
.onErrorResume(CsrfException.class, (ex) -> this.accessDeniedHandler.handle(exchange, ex));
return this.requireCsrfProtectionMatcher.matches(exchange)
.filter(MatchResult::isMatch)
.filter((matchResult) -> !exchange.getAttributes().containsKey(CsrfToken.class.getName()))
.flatMap((m) -> validateToken(exchange))
.flatMap((m) -> continueFilterChain(exchange, chain))
.switchIfEmpty(continueFilterChain(exchange, chain).then(Mono.empty()))
.onErrorResume(CsrfException.class, (ex) -> this.accessDeniedHandler.handle(exchange, ex));
}
public static void skipExchange(ServerWebExchange exchange) {
@@ -131,15 +133,15 @@ public class CsrfWebFilter implements WebFilter {
private Mono<Void> validateToken(ServerWebExchange exchange) {
return this.csrfTokenRepository.loadToken(exchange)
.switchIfEmpty(
Mono.defer(() -> Mono.error(new CsrfException("An expected CSRF token cannot be found"))))
.filterWhen((expected) -> containsValidCsrfToken(exchange, expected))
.switchIfEmpty(Mono.defer(() -> Mono.error(new CsrfException("Invalid CSRF Token")))).then();
.switchIfEmpty(Mono.defer(() -> Mono.error(new CsrfException("An expected CSRF token cannot be found"))))
.filterWhen((expected) -> containsValidCsrfToken(exchange, expected))
.switchIfEmpty(Mono.defer(() -> Mono.error(new CsrfException("Invalid CSRF Token"))))
.then();
}
private Mono<Boolean> containsValidCsrfToken(ServerWebExchange exchange, CsrfToken expected) {
return this.requestHandler.resolveCsrfTokenValue(exchange, expected)
.map((actual) -> equalsConstantTime(actual, expected.getToken()));
.map((actual) -> equalsConstantTime(actual, expected.getToken()));
}
private Mono<Void> continueFilterChain(ServerWebExchange exchange, WebFilterChain chain) {
@@ -175,7 +177,8 @@ public class CsrfWebFilter implements WebFilter {
private Mono<CsrfToken> generateToken(ServerWebExchange exchange) {
return this.csrfTokenRepository.generateToken(exchange)
.delayUntil((token) -> this.csrfTokenRepository.saveToken(exchange, token)).cache();
.delayUntil((token) -> this.csrfTokenRepository.saveToken(exchange, token))
.cache();
}
private static class DefaultRequireCsrfProtectionMatcher implements ServerWebExchangeMatcher {
@@ -185,9 +188,11 @@ public class CsrfWebFilter implements WebFilter {
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest()).flatMap((r) -> Mono.justOrEmpty(r.getMethod()))
.filter(ALLOWED_METHODS::contains).flatMap((m) -> MatchResult.notMatch())
.switchIfEmpty(MatchResult.match());
return Mono.just(exchange.getRequest())
.flatMap((r) -> Mono.justOrEmpty(r.getMethod()))
.filter(ALLOWED_METHODS::contains)
.flatMap((m) -> MatchResult.notMatch())
.switchIfEmpty(MatchResult.match());
}
}
@@ -47,7 +47,7 @@ public class ServerCsrfTokenRequestAttributeHandler implements ServerCsrfTokenRe
@Override
public Mono<String> resolveCsrfTokenValue(ServerWebExchange exchange, CsrfToken csrfToken) {
return ServerCsrfTokenRequestHandler.super.resolveCsrfTokenValue(exchange, csrfToken)
.switchIfEmpty(tokenFromMultipartData(exchange, csrfToken));
.switchIfEmpty(tokenFromMultipartData(exchange, csrfToken));
}
/**
@@ -70,8 +70,10 @@ public class ServerCsrfTokenRequestAttributeHandler implements ServerCsrfTokenRe
if (!MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
return Mono.empty();
}
return exchange.getMultipartData().map((d) -> d.getFirst(expected.getParameterName())).cast(FormFieldPart.class)
.map(FormFieldPart::value);
return exchange.getMultipartData()
.map((d) -> d.getFirst(expected.getParameterName()))
.cast(FormFieldPart.class)
.map(FormFieldPart::value);
}
}
@@ -46,9 +46,9 @@ public interface ServerCsrfTokenRequestHandler extends ServerCsrfTokenRequestRes
default Mono<String> resolveCsrfTokenValue(ServerWebExchange exchange, CsrfToken csrfToken) {
Assert.notNull(exchange, "exchange cannot be null");
Assert.notNull(csrfToken, "csrfToken cannot be null");
return exchange.getFormData().flatMap((data) -> Mono.justOrEmpty(data.getFirst(csrfToken.getParameterName())))
.switchIfEmpty(
Mono.justOrEmpty(exchange.getRequest().getHeaders().getFirst(csrfToken.getHeaderName())));
return exchange.getFormData()
.flatMap((data) -> Mono.justOrEmpty(data.getFirst(csrfToken.getParameterName())))
.switchIfEmpty(Mono.justOrEmpty(exchange.getRequest().getHeaders().getFirst(csrfToken.getHeaderName())));
}
}
@@ -41,7 +41,7 @@ public class WebSessionServerCsrfTokenRepository implements ServerCsrfTokenRepos
private static final String DEFAULT_CSRF_HEADER_NAME = "X-CSRF-TOKEN";
private static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = WebSessionServerCsrfTokenRepository.class.getName()
.concat(".CSRF_TOKEN");
.concat(".CSRF_TOKEN");
private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;
@@ -56,8 +56,9 @@ public class WebSessionServerCsrfTokenRepository implements ServerCsrfTokenRepos
@Override
public Mono<Void> saveToken(ServerWebExchange exchange, CsrfToken token) {
return exchange.getSession().doOnNext((session) -> putToken(session.getAttributes(), token))
.flatMap((session) -> session.changeSessionId());
return exchange.getSession()
.doOnNext((session) -> putToken(session.getAttributes(), token))
.flatMap((session) -> session.changeSessionId());
}
private void putToken(Map<String, Object> attributes, CsrfToken token) {
@@ -71,8 +72,9 @@ public class WebSessionServerCsrfTokenRepository implements ServerCsrfTokenRepos
@Override
public Mono<CsrfToken> loadToken(ServerWebExchange exchange) {
return exchange.getSession().filter((session) -> session.getAttributes().containsKey(this.sessionAttributeName))
.map((session) -> session.getAttribute(this.sessionAttributeName));
return exchange.getSession()
.filter((session) -> session.getAttributes().containsKey(this.sessionAttributeName))
.map((session) -> session.getAttribute(this.sessionAttributeName));
}
/**
@@ -52,16 +52,18 @@ public final class XorServerCsrfTokenRequestAttributeHandler extends ServerCsrfT
public void handle(ServerWebExchange exchange, Mono<CsrfToken> csrfToken) {
Assert.notNull(exchange, "exchange cannot be null");
Assert.notNull(csrfToken, "csrfToken cannot be null");
Mono<CsrfToken> updatedCsrfToken = csrfToken.map((token) -> new DefaultCsrfToken(token.getHeaderName(),
token.getParameterName(), createXoredCsrfToken(this.secureRandom, token.getToken())))
.cast(CsrfToken.class).cache();
Mono<CsrfToken> updatedCsrfToken = csrfToken
.map((token) -> new DefaultCsrfToken(token.getHeaderName(), token.getParameterName(),
createXoredCsrfToken(this.secureRandom, token.getToken())))
.cast(CsrfToken.class)
.cache();
super.handle(exchange, updatedCsrfToken);
}
@Override
public Mono<String> resolveCsrfTokenValue(ServerWebExchange exchange, CsrfToken csrfToken) {
return super.resolveCsrfTokenValue(exchange, csrfToken)
.flatMap((actualToken) -> Mono.justOrEmpty(getTokenValue(actualToken, csrfToken.getToken())));
.flatMap((actualToken) -> Mono.justOrEmpty(getTokenValue(actualToken, csrfToken.getToken())));
}
private static String getTokenValue(String actualToken, String token) {
@@ -55,9 +55,10 @@ public class CacheControlServerHttpHeadersWriter implements ServerHttpHeadersWri
* The delegate to write all the cache control related headers
*/
private static final ServerHttpHeadersWriter CACHE_HEADERS = StaticServerHttpHeadersWriter.builder()
.header(HttpHeaders.CACHE_CONTROL, CacheControlServerHttpHeadersWriter.CACHE_CONTRTOL_VALUE)
.header(HttpHeaders.PRAGMA, CacheControlServerHttpHeadersWriter.PRAGMA_VALUE)
.header(HttpHeaders.EXPIRES, CacheControlServerHttpHeadersWriter.EXPIRES_VALUE).build();
.header(HttpHeaders.CACHE_CONTROL, CacheControlServerHttpHeadersWriter.CACHE_CONTRTOL_VALUE)
.header(HttpHeaders.PRAGMA, CacheControlServerHttpHeadersWriter.PRAGMA_VALUE)
.header(HttpHeaders.EXPIRES, CacheControlServerHttpHeadersWriter.EXPIRES_VALUE)
.build();
@Override
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
@@ -50,7 +50,8 @@ public final class ClearSiteDataServerHttpHeadersWriter implements ServerHttpHea
public ClearSiteDataServerHttpHeadersWriter(Directive... directives) {
Assert.notEmpty(directives, "directives cannot be empty or null");
this.headerWriterDelegate = StaticServerHttpHeadersWriter.builder()
.header(CLEAR_SITE_DATA_HEADER, transformToHeaderValue(directives)).build();
.header(CLEAR_SITE_DATA_HEADER, transformToHeaderValue(directives))
.build();
}
@Override
@@ -36,7 +36,8 @@ public class ContentTypeOptionsServerHttpHeadersWriter implements ServerHttpHead
* The delegate to write all the cache control related headers
*/
private static final ServerHttpHeadersWriter CONTENT_TYPE_HEADERS = StaticServerHttpHeadersWriter.builder()
.header(X_CONTENT_OPTIONS, NOSNIFF).build();
.header(X_CONTENT_OPTIONS, NOSNIFF)
.build();
@Override
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
@@ -62,8 +62,10 @@ public final class ServerWebExchangeDelegatingServerHttpHeadersWriter implements
@Override
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
return this.headersWriter.getMatcher().matches(exchange).filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> this.headersWriter.getEntry().writeHttpHeaders(exchange));
return this.headersWriter.getMatcher()
.matches(exchange)
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.flatMap((matchResult) -> this.headersWriter.getEntry().writeHttpHeaders(exchange));
}
}
@@ -36,7 +36,8 @@ public class XContentTypeOptionsServerHttpHeadersWriter implements ServerHttpHea
* The delegate to write all the cache control related headers
*/
private static final ServerHttpHeadersWriter CONTENT_TYPE_HEADERS = StaticServerHttpHeadersWriter.builder()
.header(X_CONTENT_OPTIONS, NOSNIFF).build();
.header(X_CONTENT_OPTIONS, NOSNIFF)
.build();
@Override
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
@@ -72,27 +72,35 @@ public class CookieServerRequestCache implements ServerRequestCache {
@Override
public Mono<Void> saveRequest(ServerWebExchange exchange) {
return this.saveRequestMatcher.matches(exchange).filter((m) -> m.isMatch()).map((m) -> exchange.getResponse())
.map(ServerHttpResponse::getCookies).doOnNext((cookies) -> {
ResponseCookie redirectUriCookie = createRedirectUriCookie(exchange.getRequest());
cookies.add(REDIRECT_URI_COOKIE_NAME, redirectUriCookie);
logger.debug(LogMessage.format("Request added to Cookie: %s", redirectUriCookie));
}).then();
return this.saveRequestMatcher.matches(exchange)
.filter((m) -> m.isMatch())
.map((m) -> exchange.getResponse())
.map(ServerHttpResponse::getCookies)
.doOnNext((cookies) -> {
ResponseCookie redirectUriCookie = createRedirectUriCookie(exchange.getRequest());
cookies.add(REDIRECT_URI_COOKIE_NAME, redirectUriCookie);
logger.debug(LogMessage.format("Request added to Cookie: %s", redirectUriCookie));
})
.then();
}
@Override
public Mono<URI> getRedirectUri(ServerWebExchange exchange) {
MultiValueMap<String, HttpCookie> cookieMap = exchange.getRequest().getCookies();
return Mono.justOrEmpty(cookieMap.getFirst(REDIRECT_URI_COOKIE_NAME)).map(HttpCookie::getValue)
.map(CookieServerRequestCache::decodeCookie)
.onErrorResume(IllegalArgumentException.class, (ex) -> Mono.empty()).map(URI::create);
return Mono.justOrEmpty(cookieMap.getFirst(REDIRECT_URI_COOKIE_NAME))
.map(HttpCookie::getValue)
.map(CookieServerRequestCache::decodeCookie)
.onErrorResume(IllegalArgumentException.class, (ex) -> Mono.empty())
.map(URI::create);
}
@Override
public Mono<ServerHttpRequest> removeMatchingRequest(ServerWebExchange exchange) {
return Mono.just(exchange.getResponse()).map(ServerHttpResponse::getCookies).doOnNext(
(cookies) -> cookies.add(REDIRECT_URI_COOKIE_NAME, invalidateRedirectUriCookie(exchange.getRequest())))
.thenReturn(exchange.getRequest());
return Mono.just(exchange.getResponse())
.map(ServerHttpResponse::getCookies)
.doOnNext((cookies) -> cookies.add(REDIRECT_URI_COOKIE_NAME,
invalidateRedirectUriCookie(exchange.getRequest())))
.thenReturn(exchange.getRequest());
}
private static ResponseCookie createRedirectUriCookie(ServerHttpRequest request) {
@@ -108,8 +116,12 @@ public class CookieServerRequestCache implements ServerRequestCache {
private static ResponseCookie createResponseCookie(ServerHttpRequest request, String cookieValue, Duration age) {
return ResponseCookie.from(REDIRECT_URI_COOKIE_NAME, cookieValue)
.path(request.getPath().contextPath().value() + "/").maxAge(age).httpOnly(true)
.secure("https".equalsIgnoreCase(request.getURI().getScheme())).sameSite("Lax").build();
.path(request.getPath().contextPath().value() + "/")
.maxAge(age)
.httpOnly(true)
.secure("https".equalsIgnoreCase(request.getURI().getScheme()))
.sameSite("Lax")
.build();
}
private static String encodeCookie(String cookieValue) {
@@ -35,8 +35,10 @@ public class ServerRequestCacheWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.requestCache.removeMatchingRequest(exchange).map((r) -> exchange.mutate().request(r).build())
.defaultIfEmpty(exchange).flatMap((e) -> chain.filter(e));
return this.requestCache.removeMatchingRequest(exchange)
.map((r) -> exchange.mutate().request(r).build())
.defaultIfEmpty(exchange)
.flatMap((e) -> chain.filter(e));
}
public void setRequestCache(ServerRequestCache requestCache) {
@@ -73,19 +73,23 @@ public class WebSessionServerRequestCache implements ServerRequestCache {
@Override
public Mono<Void> saveRequest(ServerWebExchange exchange) {
return this.saveRequestMatcher.matches(exchange).filter(MatchResult::isMatch)
.flatMap((m) -> exchange.getSession()).map(WebSession::getAttributes).doOnNext((attrs) -> {
String requestPath = pathInApplication(exchange.getRequest());
attrs.put(this.sessionAttrName, requestPath);
logger.debug(LogMessage.format("Request added to WebSession: '%s'", requestPath));
}).then();
return this.saveRequestMatcher.matches(exchange)
.filter(MatchResult::isMatch)
.flatMap((m) -> exchange.getSession())
.map(WebSession::getAttributes)
.doOnNext((attrs) -> {
String requestPath = pathInApplication(exchange.getRequest());
attrs.put(this.sessionAttrName, requestPath);
logger.debug(LogMessage.format("Request added to WebSession: '%s'", requestPath));
})
.then();
}
@Override
public Mono<URI> getRedirectUri(ServerWebExchange exchange) {
return exchange.getSession()
.flatMap((session) -> Mono.justOrEmpty(session.<String>getAttribute(this.sessionAttrName)))
.map(this::createRedirectUri);
.flatMap((session) -> Mono.justOrEmpty(session.<String>getAttribute(this.sessionAttrName)))
.map(this::createRedirectUri);
}
@Override
@@ -53,10 +53,13 @@ public final class HttpsRedirectWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return Mono.just(exchange).filter(this::isInsecure).flatMap(this.requiresHttpsRedirectMatcher::matches)
.filter((matchResult) -> matchResult.isMatch()).switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.map((matchResult) -> createRedirectUri(exchange))
.flatMap((uri) -> this.redirectStrategy.sendRedirect(exchange, uri));
return Mono.just(exchange)
.filter(this::isInsecure)
.flatMap(this.requiresHttpsRedirectMatcher::matches)
.filter((matchResult) -> matchResult.isMatch())
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.map((matchResult) -> createRedirectUri(exchange))
.flatMap((uri) -> this.redirectStrategy.sendRedirect(exchange, uri));
}
/**
@@ -63,8 +63,10 @@ public class LoginPageGeneratingWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.matcher.matches(exchange).filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.switchIfEmpty(chain.filter(exchange).then(Mono.empty())).flatMap((matchResult) -> render(exchange));
return this.matcher.matches(exchange)
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((matchResult) -> render(exchange));
}
private Mono<Void> render(ServerWebExchange exchange) {
@@ -148,7 +150,7 @@ public class LoginPageGeneratingWebFilter implements WebFilter {
sb.append(createError(isError));
sb.append("<table class=\"table table-striped\">\n");
for (Map.Entry<String, String> clientAuthenticationUrlToClientName : oauth2AuthenticationUrlToClientName
.entrySet()) {
.entrySet()) {
sb.append(" <tr><td>");
String url = clientAuthenticationUrlToClientName.getKey();
sb.append("<a href=\"").append(contextPath).append(url).append("\">");
@@ -45,8 +45,10 @@ public class LogoutPageGeneratingWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.matcher.matches(exchange).filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.switchIfEmpty(chain.filter(exchange).then(Mono.empty())).flatMap((matchResult) -> render(exchange));
return this.matcher.matches(exchange)
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((matchResult) -> render(exchange));
}
private Mono<Void> render(ServerWebExchange exchange) {
@@ -58,12 +58,13 @@ public class AndServerWebExchangeMatcher implements ServerWebExchangeMatcher {
return Mono.defer(() -> {
Map<String, Object> variables = new HashMap<>();
return Flux.fromIterable(this.matchers)
.doOnNext((matcher) -> logger.debug(LogMessage.format("Trying to match using %s", matcher)))
.flatMap((matcher) -> matcher.matches(exchange))
.doOnNext((matchResult) -> variables.putAll(matchResult.getVariables())).all(MatchResult::isMatch)
.flatMap((allMatch) -> allMatch ? MatchResult.match(variables) : MatchResult.notMatch())
.doOnNext((matchResult) -> logger
.debug(matchResult.isMatch() ? "All requestMatchers returned true" : "Did not match"));
.doOnNext((matcher) -> logger.debug(LogMessage.format("Trying to match using %s", matcher)))
.flatMap((matcher) -> matcher.matches(exchange))
.doOnNext((matchResult) -> variables.putAll(matchResult.getVariables()))
.all(MatchResult::isMatch)
.flatMap((allMatch) -> allMatch ? MatchResult.match(variables) : MatchResult.notMatch())
.doOnNext((matchResult) -> logger
.debug(matchResult.isMatch() ? "All requestMatchers returned true" : "Did not match"));
});
}
@@ -45,8 +45,9 @@ public class NegatedServerWebExchangeMatcher implements ServerWebExchangeMatcher
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
return this.matcher.matches(exchange).flatMap(this::negate)
.doOnNext((matchResult) -> logger.debug(LogMessage.format("matches = %s", matchResult.isMatch())));
return this.matcher.matches(exchange)
.flatMap(this::negate)
.doOnNext((matchResult) -> logger.debug(LogMessage.format("matches = %s", matchResult.isMatch())));
}
private Mono<MatchResult> negate(MatchResult matchResult) {
@@ -54,10 +54,12 @@ public class OrServerWebExchangeMatcher implements ServerWebExchangeMatcher {
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
return Flux.fromIterable(this.matchers)
.doOnNext((matcher) -> logger.debug(LogMessage.format("Trying to match using %s", matcher)))
.flatMap((matcher) -> matcher.matches(exchange)).filter(MatchResult::isMatch).next()
.switchIfEmpty(MatchResult.notMatch())
.doOnNext((matchResult) -> logger.debug(matchResult.isMatch() ? "matched" : "No matches found"));
.doOnNext((matcher) -> logger.debug(LogMessage.format("Trying to match using %s", matcher)))
.flatMap((matcher) -> matcher.matches(exchange))
.filter(MatchResult::isMatch)
.next()
.switchIfEmpty(MatchResult.notMatch())
.doOnNext((matchResult) -> logger.debug(matchResult.isMatch() ? "matched" : "No matches found"));
}
@Override
@@ -96,8 +96,8 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe
Map<String, String> pathVariables = this.pattern.matchAndExtract(path).getUriVariables();
Map<String, Object> variables = new HashMap<>(pathVariables);
if (logger.isDebugEnabled()) {
logger.debug(
"Checking match of request : '" + path + "'; against '" + this.pattern.getPatternString() + "'");
logger
.debug("Checking match of request : '" + path + "'; against '" + this.pattern.getPatternString() + "'");
}
return MatchResult.match(variables);
}
@@ -183,7 +183,7 @@ public class MvcRequestMatcher implements RequestMatcher, RequestVariablesExtrac
String lookupPath = this.pathHelper.getLookupPathForRequest(request);
if (matches(lookupPath)) {
Map<String, String> variables = this.pathMatcher
.extractUriTemplateVariables(MvcRequestMatcher.this.pattern, lookupPath);
.extractUriTemplateVariables(MvcRequestMatcher.this.pattern, lookupPath);
return MatchResult.match(variables);
}
return MatchResult.notMatch();
@@ -79,7 +79,7 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
private Log logger = LogFactory.getLog(getClass());
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private final String rolePrefix;
@@ -238,14 +238,14 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
}
AuthenticationManager authManager = HttpServlet3RequestFactory.this.authenticationManager;
if (authManager == null) {
HttpServlet3RequestFactory.this.logger.debug(
"authenticationManager is null, so allowing original HttpServletRequest to handle login");
HttpServlet3RequestFactory.this.logger
.debug("authenticationManager is null, so allowing original HttpServletRequest to handle login");
super.login(username, password);
return;
}
Authentication authentication = getAuthentication(authManager, username, password);
SecurityContext context = HttpServlet3RequestFactory.this.securityContextHolderStrategy
.createEmptyContext();
.createEmptyContext();
context.setAuthentication(authentication);
HttpServlet3RequestFactory.this.securityContextHolderStrategy.setContext(context);
HttpServlet3RequestFactory.this.securityContextRepository.saveContext(context, this, this.response);
@@ -255,7 +255,7 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
throws ServletException {
try {
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken
.unauthenticated(username, password);
.unauthenticated(username, password);
Object details = HttpServlet3RequestFactory.this.authenticationDetailsSource.buildDetails(this);
authentication.setDetails(details);
return authManager.authenticate(authentication);
@@ -271,12 +271,12 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
List<LogoutHandler> handlers = HttpServlet3RequestFactory.this.logoutHandlers;
if (CollectionUtils.isEmpty(handlers)) {
HttpServlet3RequestFactory.this.logger
.debug("logoutHandlers is null, so allowing original HttpServletRequest to handle logout");
.debug("logoutHandlers is null, so allowing original HttpServletRequest to handle logout");
super.logout();
return;
}
Authentication authentication = HttpServlet3RequestFactory.this.securityContextHolderStrategy.getContext()
.getAuthentication();
.getAuthentication();
for (LogoutHandler handler : handlers) {
handler.logout(this, this.response, authentication);
}
@@ -72,7 +72,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private String rolePrefix = "ROLE_";
@@ -52,7 +52,7 @@ import org.springframework.util.Assert;
public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequestWrapper {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private final AuthenticationTrustResolver trustResolver;
@@ -69,7 +69,7 @@ import org.springframework.web.filter.GenericFilterBean;
public class ConcurrentSessionFilter extends GenericFilterBean {
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private final SessionRegistry sessionRegistry;
@@ -138,10 +138,10 @@ public class ConcurrentSessionFilter extends GenericFilterBean {
if (info.isExpired()) {
// Expired - abort processing
this.logger.debug(LogMessage
.of(() -> "Requested session ID " + request.getRequestedSessionId() + " has expired."));
.of(() -> "Requested session ID " + request.getRequestedSessionId() + " has expired."));
doLogout(request, response);
this.sessionInformationExpiredStrategy
.onExpiredSessionDetected(new SessionInformationExpiredEvent(info, request, response));
.onExpiredSessionDetected(new SessionInformationExpiredEvent(info, request, response));
return;
}
// Non-expired - update last request date/time
@@ -221,8 +221,9 @@ public class ConcurrentSessionFilter extends GenericFilterBean {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {
HttpServletResponse response = event.getResponse();
response.getWriter().print("This session has been expired (possibly due to multiple concurrent "
+ "logins being attempted as the same user).");
response.getWriter()
.print("This session has been expired (possibly due to multiple concurrent "
+ "logins being attempted as the same user).");
response.flushBuffer();
}
@@ -43,8 +43,11 @@ public final class RequestedUrlRedirectInvalidSessionStrategy implements Invalid
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException {
String destinationUrl = ServletUriComponentsBuilder.fromRequest(request).host(null).scheme(null).port(null)
.toUriString();
String destinationUrl = ServletUriComponentsBuilder.fromRequest(request)
.host(null)
.scheme(null)
.port(null)
.toUriString();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Starting new session (if required) and redirecting to '" + destinationUrl + "'");
}
@@ -55,7 +55,7 @@ public class SessionManagementFilter extends GenericFilterBean {
static final String FILTER_APPLIED = "__spring_security_session_mgmt_filter_applied";
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy();
.getContextHolderStrategy();
private final SecurityContextRepository securityContextRepository;
@@ -61,7 +61,7 @@ public class DefaultRedirectStrategyTests {
request.setContextPath("/context");
MockHttpServletResponse response = new MockHttpServletResponse();
assertThatIllegalArgumentException()
.isThrownBy(() -> rds.sendRedirect(request, response, "https://redirectme.somewhere.else"));
.isThrownBy(() -> rds.sendRedirect(request, response, "https://redirectme.somewhere.else"));
}
}
@@ -201,10 +201,10 @@ public class FilterChainProxyTests {
given(this.matcher.matches(any(HttpServletRequest.class))).willReturn(true);
willAnswer((Answer<Object>) (inv) -> {
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("username", "password"));
.setAuthentication(new TestingAuthenticationToken("username", "password"));
return null;
}).given(this.filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(FilterChain.class));
}).given(this.filter)
.doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));
this.fcp.doFilter(this.request, this.response, this.chain);
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
}
@@ -223,12 +223,12 @@ public class FilterChainProxyTests {
given(this.matcher.matches(any(HttpServletRequest.class))).willReturn(true);
willAnswer((Answer<Object>) (inv) -> {
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("username", "password"));
.setAuthentication(new TestingAuthenticationToken("username", "password"));
throw new ServletException("oops");
}).given(this.filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(FilterChain.class));
}).given(this.filter)
.doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));
assertThatExceptionOfType(ServletException.class)
.isThrownBy(() -> this.fcp.doFilter(this.request, this.response, this.chain));
.isThrownBy(() -> this.fcp.doFilter(this.request, this.response, this.chain));
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
}
@@ -243,13 +243,13 @@ public class FilterChainProxyTests {
willAnswer((Answer<Object>) (inv1) -> {
innerChain.doFilter(this.request, this.response);
return null;
}).given(this.filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(FilterChain.class));
}).given(this.filter)
.doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));
this.fcp.doFilter(this.request, this.response, innerChain);
assertThat(SecurityContextHolder.getContext().getAuthentication()).isSameAs(expected);
return null;
}).given(this.filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(FilterChain.class));
}).given(this.filter)
.doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));
this.fcp.doFilter(this.request, this.response, this.chain);
verify(innerChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
@@ -297,7 +297,8 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
filter.doFilter(this.request, this.response, this.chain);
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(4)).onStart(captor.capture());
@@ -323,7 +324,8 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
filter.doFilter(this.request, this.response, this.chain);
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(4)).onStart(captor.capture());
@@ -345,7 +347,8 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
filter.doFilter(this.request, this.response, this.chain);
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(2)).onStart(captor.capture());
@@ -367,9 +370,10 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.chain));
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.chain));
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(2)).onStart(captor.capture());
verify(handler, times(2)).onStop(any());
@@ -394,9 +398,10 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.chain));
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.chain));
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(2)).onStart(captor.capture());
verify(handler, times(2)).onStop(any());
@@ -419,7 +424,8 @@ public class FilterChainProxyTests {
FilterChainProxy fcp = new FilterChainProxy(sec);
fcp.setFilterChainDecorator(new ObservationFilterChainDecorator(registry));
Filter filter = ObservationFilterChainDecorator.FilterObservation
.create(Observation.createNotStarted("wrap", registry)).wrap(fcp);
.create(Observation.createNotStarted("wrap", registry))
.wrap(fcp);
filter.doFilter(this.request, this.response, this.chain);
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(3)).onStart(captor.capture());
@@ -434,7 +440,7 @@ public class FilterChainProxyTests {
assertThat(context).isInstanceOf(ObservationFilterChainDecorator.FilterChainObservationContext.class);
ObservationFilterChainDecorator.FilterChainObservationContext filterChainObservationContext = (ObservationFilterChainDecorator.FilterChainObservationContext) context;
assertThat(context.getName())
.isEqualTo(ObservationFilterChainDecorator.FilterChainObservationConvention.CHAIN_OBSERVATION_NAME);
.isEqualTo(ObservationFilterChainDecorator.FilterChainObservationConvention.CHAIN_OBSERVATION_NAME);
assertThat(context.getContextualName()).endsWith(filterSection);
assertThat(filterChainObservationContext.getChainPosition()).isEqualTo(chainPosition);
}
@@ -77,14 +77,14 @@ public class FilterInvocationTests {
public void testRejectsNullServletRequest() {
MockHttpServletResponse response = new MockHttpServletResponse();
assertThatIllegalArgumentException()
.isThrownBy(() -> new FilterInvocation(null, response, mock(FilterChain.class)));
.isThrownBy(() -> new FilterInvocation(null, response, mock(FilterChain.class)));
}
@Test
public void testRejectsNullServletResponse() {
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
assertThatIllegalArgumentException()
.isThrownBy(() -> new FilterInvocation(request, null, mock(FilterChain.class)));
.isThrownBy(() -> new FilterInvocation(request, null, mock(FilterChain.class)));
}
@Test
@@ -123,7 +123,7 @@ public class FilterInvocationTests {
@Test
public void dummyChainRejectsInvocation() throws Exception {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> FilterInvocation.DUMMY_CHAIN
.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class)));
.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class)));
}
@Test
@@ -147,7 +147,7 @@ public class ObservationFilterChainDecoratorTests {
ArgumentCaptor<Observation.Context> context = ArgumentCaptor.forClass(Observation.Context.class);
verify(handler, times(3)).onScopeClosed(context.capture());
assertThat(context.getValue().getLowCardinalityKeyValue("spring.security.reached.filter.name").getValue())
.isEqualTo(expectedFilterNameTag);
.isEqualTo(expectedFilterNameTag);
}
static Stream<Arguments> decorateFiltersWhenCompletesThenHasSpringSecurityReachedFilterNameTag() {

Some files were not shown because too many files have changed in this diff Show More