Remove @NullUnmarked

Closes gh-18491
This commit is contained in:
Robert Winch 2026-01-20 11:10:29 -06:00 committed by Rob Winch
parent 3f66d8b770
commit 9f8ac34c3b
12 changed files with 85 additions and 90 deletions

View File

@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
import org.apereo.cas.client.validation.Assertion;
import org.apereo.cas.client.validation.TicketValidationException;
import org.apereo.cas.client.validation.TicketValidator;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
@ -166,7 +165,6 @@ public class CasAuthenticationProvider implements AuthenticationProvider, Initia
* @param authentication
* @return
*/
@NullUnmarked
private @Nullable String getServiceUrl(Authentication authentication) {
String serviceUrl;
if (authentication.getDetails() instanceof ServiceAuthenticationDetails) {

View File

@ -19,7 +19,7 @@ package org.springframework.security.access.expression.method;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
@ -45,13 +45,11 @@ class MethodSecurityEvaluationContext extends MethodBasedEvaluationContext {
* for each instance. Use the constructor which takes the resolver, as an argument
* thus allowing for caching.
*/
MethodSecurityEvaluationContext(Authentication user, MethodInvocation mi) {
MethodSecurityEvaluationContext(@Nullable Authentication user, MethodInvocation mi) {
this(user, mi, new DefaultSecurityParameterNameDiscoverer());
}
@NullUnmarked // FIXME: rootObject in MethodBasedEvaluationContext is non-null
// (probably needs changed) but StandardEvaluationContext is Nullable
MethodSecurityEvaluationContext(Authentication user, MethodInvocation mi,
MethodSecurityEvaluationContext(@Nullable Authentication user, MethodInvocation mi,
ParameterNameDiscoverer parameterNameDiscoverer) {
super(mi.getThis(), getSpecificMethod(mi), mi.getArguments(), parameterNameDiscoverer);
}

View File

@ -18,7 +18,6 @@ package org.springframework.security.messaging.handler.invocation.reactive;
import java.lang.annotation.Annotation;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
@ -152,9 +151,11 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg
// @formatter:on
}
@NullUnmarked
private @Nullable Object resolvePrincipal(MethodParameter parameter, @Nullable Object principal) {
AuthenticationPrincipal authPrincipal = findMethodAnnotation(parameter);
if (authPrincipal == null) {
return null;
}
String expressionToParse = authPrincipal.expression();
if (StringUtils.hasLength(expressionToParse)) {
StandardEvaluationContext context = new StandardEvaluationContext();

View File

@ -24,7 +24,6 @@ import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.context.ApplicationContext;
@ -180,7 +179,6 @@ public abstract class AbstractAuthorizeTag {
return this.method;
}
@NullUnmarked
public void setMethod(String method) {
this.method = (method != null) ? method.toUpperCase(Locale.ENGLISH) : null;
}

View File

@ -20,7 +20,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.function.Supplier;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeanUtils;
@ -28,6 +27,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@ -40,6 +41,7 @@ import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.Assert;
/**
* A {@link TestExecutionListener} that will find annotations that are annotated with
@ -79,7 +81,6 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
* {@link WithSecurityContext} on it. If that is not found, the class is inspected. If
* still not found, then no {@link SecurityContext} is populated.
*/
@NullUnmarked
@Override
public void beforeTestMethod(TestContext testContext) {
TestSecurityContext testSecurityContext = createTestSecurityContext(testContext.getTestMethod(), testContext);
@ -102,7 +103,6 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
* If configured before test execution sets the SecurityContext
* @since 5.1
*/
@NullUnmarked
@Override
public void beforeTestExecution(TestContext testContext) {
Supplier<SecurityContext> supplier = (Supplier<SecurityContext>) testContext
@ -129,7 +129,6 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
return createTestSecurityContext(rootDeclaringClass, withSecurityContext, context);
}
@NullUnmarked
@SuppressWarnings({ "rawtypes", "unchecked" })
private @Nullable TestSecurityContext createTestSecurityContext(AnnotatedElement annotated,
@Nullable WithSecurityContext withSecurityContext, TestContext context) {
@ -140,7 +139,9 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
WithSecurityContextFactory factory = createFactory(withSecurityContext, context);
Class<? extends Annotation> type = (Class<? extends Annotation>) GenericTypeResolver
.resolveTypeArgument(factory.getClass(), WithSecurityContextFactory.class);
Assert.isTrue(type != null, factory.getClass() + " must specify a Type argument");
Annotation annotation = findAnnotation(annotated, type);
Assert.isTrue(annotation != null, "No annotation found for " + type + " on " + annotated);
Supplier<SecurityContext> supplier = () -> {
try {
return factory.createSecurityContext(annotation);
@ -153,22 +154,23 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
return new TestSecurityContext(supplier, initialize);
}
@NullUnmarked
private @Nullable Annotation findAnnotation(AnnotatedElement annotated,
@Nullable Class<? extends Annotation> type) {
private @Nullable Annotation findAnnotation(AnnotatedElement annotated, Class<? extends Annotation> type) {
Annotation findAnnotation = AnnotatedElementUtils.findMergedAnnotation(annotated, type);
if (findAnnotation != null) {
return findAnnotation;
}
Annotation[] allAnnotations = AnnotationUtils.getAnnotations(annotated);
for (Annotation annotationToTest : allAnnotations) {
WithSecurityContext withSecurityContext = AnnotationUtils.findAnnotation(annotationToTest.annotationType(),
WithSecurityContext.class);
if (withSecurityContext != null) {
return annotationToTest;
}
}
return null;
MergedAnnotations allAnnotations = MergedAnnotations.from(annotated);
// @formatter:off
return allAnnotations.stream()
.filter((annotationToTest) -> {
WithSecurityContext withSecurityContext = AnnotationUtils.findAnnotation(annotationToTest.getType(),
WithSecurityContext.class);
return withSecurityContext != null;
})
.map(MergedAnnotation::synthesize)
.findFirst()
.orElse(null);
// @formatter:on
}
private WithSecurityContextFactory<? extends Annotation> createFactory(WithSecurityContext withSecurityContext,
@ -189,7 +191,6 @@ public class WithSecurityContextTestExecutionListener extends AbstractTestExecut
* Clears out the {@link TestSecurityContextHolder} and the
* {@link SecurityContextHolder} after each test method.
*/
@NullUnmarked
@Override
public void afterTestMethod(TestContext testContext) {
this.securityContextHolderStrategyConverter.convert(testContext).clearContext();

View File

@ -29,13 +29,12 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@ -191,7 +190,6 @@ public final class SecurityMockServerConfigurers {
* @return the {@link OAuth2LoginMutator} to further configure or use
* @since 5.3
*/
@NullUnmarked
public static OAuth2LoginMutator mockOAuth2Login() {
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token", null,
null, Collections.singleton("read"));
@ -205,7 +203,6 @@ public final class SecurityMockServerConfigurers {
* @return the {@link OidcLoginMutator} to further configure or use
* @since 5.3
*/
@NullUnmarked
public static OidcLoginMutator mockOidcLogin() {
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token", null,
null, Collections.singleton("read"));
@ -255,12 +252,15 @@ public final class SecurityMockServerConfigurers {
private CsrfMutator() {
}
@NullUnmarked
@Override
public void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector) {
CsrfWebFilter filter = new CsrfWebFilter();
filter.setRequireCsrfProtectionMatcher((e) -> ServerWebExchangeMatcher.MatchResult.notMatch());
if (httpHandlerBuilder == null) {
throw new UnsupportedOperationException(
"Cannot apply Csrf because WebHttpHandlerBuilder is null. You must use mock clients.");
}
httpHandlerBuilder.filters((filters) -> filters.add(0, filter));
}
@ -398,11 +398,14 @@ public final class SecurityMockServerConfigurers {
builder.filters(addSetupMutatorFilter());
}
@NullUnmarked
@Override
public void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder webHttpHandlerBuilder,
@Nullable ClientHttpConnector clientHttpConnector) {
if (webHttpHandlerBuilder == null) {
throw new UnsupportedOperationException(
"Cannot apply Spring Security Test Support to null WebHttpHandlerBuilder. This happens when trying to integrate with non-mock based clients.");
}
webHttpHandlerBuilder.filters(addSetupMutatorFilter());
}
@ -542,10 +545,13 @@ public final class SecurityMockServerConfigurers {
configurer().afterConfigureAdded(serverSpec);
}
@NullUnmarked
@Override
public void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector) {
if (httpHandlerBuilder == null) {
throw new UnsupportedOperationException(
"Cannot apply Spring Security Test Support to null WebHttpHandlerBuilder. This happens when trying to integrate with non-mock based clients.");
}
httpHandlerBuilder.filter((exchange, chain) -> {
CsrfWebFilter.skipExchange(exchange);
return chain.filter(exchange);
@ -553,7 +559,6 @@ public final class SecurityMockServerConfigurers {
configurer().afterConfigurerAdded(builder, httpHandlerBuilder, connector);
}
@NullUnmarked
private <T extends WebTestClientConfigurer & MockServerConfigurer> T configurer() {
return mockAuthentication(
new JwtAuthenticationToken(this.jwt, this.authoritiesConverter.convert(this.jwt)));
@ -638,10 +643,13 @@ public final class SecurityMockServerConfigurers {
configurer().afterConfigureAdded(serverSpec);
}
@NullUnmarked
@Override
public void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector) {
if (httpHandlerBuilder == null) {
throw new UnsupportedOperationException(
"Cannot apply Spring Security Test Support to null WebHttpHandlerBuilder. This happens when trying to integrate with non-mock based clients.");
}
httpHandlerBuilder.filter((exchange, chain) -> {
CsrfWebFilter.skipExchange(exchange);
return chain.filter(exchange);
@ -696,8 +704,7 @@ public final class SecurityMockServerConfigurers {
return new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", issuedAt, expiresAt);
}
@NullUnmarked
private Instant getInstant(Map<String, Object> attributes, String name) {
private @Nullable Instant getInstant(Map<String, Object> attributes, String name) {
Object value = attributes.get(name);
if (value == null) {
return null;
@ -874,16 +881,14 @@ public final class SecurityMockServerConfigurers {
private OAuth2AccessToken accessToken;
@Nullable
private OidcIdToken idToken;
private @Nullable OidcIdToken idToken;
@SuppressWarnings("NullAway.Init")
private OidcUserInfo userInfo;
private Supplier<OidcUser> oidcUser = this::defaultPrincipal;
@Nullable
private Collection<GrantedAuthority> authorities;
private @Nullable Collection<GrantedAuthority> authorities;
private OidcLoginMutator(OAuth2AccessToken accessToken) {
this.accessToken = accessToken;
@ -1027,7 +1032,6 @@ public final class SecurityMockServerConfigurers {
return authorities;
}
@NullUnmarked
private OidcIdToken getOidcIdToken() {
if (this.idToken != null) {
return this.idToken;
@ -1049,13 +1053,11 @@ public final class SecurityMockServerConfigurers {
* @author Josh Cummings
* @since 5.3
*/
@NullUnmarked
public static final class OAuth2ClientMutator implements WebTestClientConfigurer, MockServerConfigurer {
private String registrationId = "test";
@Nullable
private ClientRegistration clientRegistration;
private @Nullable ClientRegistration clientRegistration;
private String principalName = "user";
@ -1130,20 +1132,24 @@ public final class SecurityMockServerConfigurers {
public void afterConfigureAdded(WebTestClient.MockServerSpec<?> serverSpec) {
}
@NullUnmarked
@Override
public void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector) {
if (httpHandlerBuilder == null) {
throw new UnsupportedOperationException(
"Cannot apply Spring Security Test Support to null WebHttpHandlerBuilder. This happens when trying to integrate with non-mock based clients.");
}
httpHandlerBuilder.filters(addAuthorizedClientFilter());
}
@NullUnmarked
private Consumer<List<WebFilter>> addAuthorizedClientFilter() {
OAuth2AuthorizedClient client = getClient();
return (filters) -> filters.add(0, (exchange, chain) -> {
ServerOAuth2AuthorizedClientRepository authorizedClientRepository = OAuth2ClientServerTestUtils
.getAuthorizedClientRepository(exchange);
if (!(authorizedClientRepository instanceof TestOAuth2AuthorizedClientRepository)) {
Assert.isTrue(authorizedClientRepository != null,
"ServerOAuth2AuthorizedClientRepository cannot be null");
authorizedClientRepository = new TestOAuth2AuthorizedClientRepository(authorizedClientRepository);
OAuth2ClientServerTestUtils.setAuthorizedClientRepository(exchange, authorizedClientRepository);
}
@ -1153,7 +1159,6 @@ public final class SecurityMockServerConfigurers {
});
}
@NullUnmarked
private OAuth2AuthorizedClient getClient() {
Assert.notNull(this.clientRegistration,
"Please specify a ClientRegistration via one of the clientRegistration methods");
@ -1181,18 +1186,18 @@ public final class SecurityMockServerConfigurers {
private final ReactiveOAuth2AuthorizedClientManager delegate;
@Nullable
private ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
private @Nullable ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
TestOAuth2AuthorizedClientManager(ReactiveOAuth2AuthorizedClientManager delegate) {
this.delegate = delegate;
}
@NullUnmarked
@Override
public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest) {
ServerWebExchange exchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
if (isEnabled(exchange)) {
Assert.isTrue(this.authorizedClientRepository != null,
"ServerOAuth2AuthorizedClientRepository not set");
return this.authorizedClientRepository.loadAuthorizedClient(
authorizeRequest.getClientRegistrationId(), authorizeRequest.getPrincipal(), exchange);
}
@ -1203,9 +1208,8 @@ public final class SecurityMockServerConfigurers {
exchange.getAttributes().put(ENABLED_ATTR_NAME, Boolean.TRUE);
}
@NullUnmarked
boolean isEnabled(@Nullable ServerWebExchange exchange) {
return Boolean.TRUE.equals(exchange.getAttribute(ENABLED_ATTR_NAME));
return exchange != null && Boolean.TRUE.equals(exchange.getAttribute(ENABLED_ATTR_NAME));
}
}
@ -1223,8 +1227,7 @@ public final class SecurityMockServerConfigurers {
private final ServerOAuth2AuthorizedClientRepository delegate;
@NullUnmarked
TestOAuth2AuthorizedClientRepository(@Nullable ServerOAuth2AuthorizedClientRepository delegate) {
TestOAuth2AuthorizedClientRepository(ServerOAuth2AuthorizedClientRepository delegate) {
this.delegate = delegate;
}
@ -1232,7 +1235,8 @@ public final class SecurityMockServerConfigurers {
public <T extends OAuth2AuthorizedClient> Mono<T> loadAuthorizedClient(String clientRegistrationId,
Authentication principal, ServerWebExchange exchange) {
if (isEnabled(exchange)) {
return Mono.just(exchange.getAttribute(TOKEN_ATTR_NAME));
T attr = exchange.getAttribute(TOKEN_ATTR_NAME);
return Mono.justOrEmpty(attr);
}
return this.delegate.loadAuthorizedClient(clientRegistrationId, principal, exchange);
}

View File

@ -40,7 +40,6 @@ import java.util.stream.Collectors;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.converter.Converter;
@ -399,7 +398,6 @@ public final class SecurityMockMvcRequestPostProcessors {
* @return the {@link OidcLoginRequestPostProcessor} for additional customization
* @since 5.3
*/
@NullUnmarked
public static OAuth2LoginRequestPostProcessor oauth2Login() {
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token", null,
null, Collections.singleton("read"));
@ -428,7 +426,6 @@ public final class SecurityMockMvcRequestPostProcessors {
* @return the {@link OidcLoginRequestPostProcessor} for additional customization
* @since 5.3
*/
@NullUnmarked
public static OidcLoginRequestPostProcessor oidcLogin() {
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "access-token", null,
null, Collections.singleton("read"));
@ -517,11 +514,11 @@ public final class SecurityMockMvcRequestPostProcessors {
private CsrfRequestPostProcessor() {
}
@NullUnmarked
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
CsrfTokenRepository repository = WebTestUtils.getCsrfTokenRepository(request);
CsrfTokenRequestHandler handler = WebTestUtils.getCsrfTokenRequestHandler(request);
Assert.isTrue(handler != null, "No CsrfTokenRequestHandler found");
if (!(repository instanceof TestCsrfTokenRepository)) {
repository = new TestCsrfTokenRepository(new HttpSessionCsrfTokenRepository());
WebTestUtils.setCsrfTokenRepository(request, repository);
@ -531,6 +528,9 @@ public final class SecurityMockMvcRequestPostProcessors {
DeferredCsrfToken deferredCsrfToken = repository.loadDeferredToken(request, response);
handler.handle(request, response, deferredCsrfToken);
CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (token == null) {
return request;
}
String tokenValue = this.useInvalidToken ? INVALID_TOKEN_VALUE : token.getToken();
if (this.asHeader) {
request.addHeader(token.getHeaderName(), tokenValue);
@ -1135,7 +1135,6 @@ public final class SecurityMockMvcRequestPostProcessors {
return this;
}
@NullUnmarked
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
CsrfFilter.skipRequest(request);
@ -1262,8 +1261,7 @@ public final class SecurityMockMvcRequestPostProcessors {
return new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", issuedAt, expiresAt);
}
@NullUnmarked
private Instant getInstant(Map<String, Object> attributes, String name) {
private @Nullable Instant getInstant(Map<String, Object> attributes, String name) {
Object value = attributes.get(name);
if (value == null) {
return null;
@ -1534,7 +1532,6 @@ public final class SecurityMockMvcRequestPostProcessors {
return authorities;
}
@NullUnmarked
private OidcIdToken getOidcIdToken() {
if (this.idToken != null) {
return this.idToken;
@ -1556,7 +1553,6 @@ public final class SecurityMockMvcRequestPostProcessors {
* @author Josh Cummings
* @since 5.3
*/
@NullUnmarked
public static final class OAuth2ClientRequestPostProcessor implements RequestPostProcessor {
private String registrationId = "test";
@ -1621,7 +1617,6 @@ public final class SecurityMockMvcRequestPostProcessors {
return this;
}
@NullUnmarked
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
if (this.clientRegistration == null) {
@ -1632,6 +1627,8 @@ public final class SecurityMockMvcRequestPostProcessors {
this.accessToken);
OAuth2AuthorizedClientRepository authorizedClientRepository = OAuth2ClientServletTestUtils
.getAuthorizedClientRepository(request);
Assert.isTrue(authorizedClientRepository != null,
"Could not find OAuth2AuthorizedClientRepository on the request");
if (!(authorizedClientRepository instanceof TestOAuth2AuthorizedClientRepository)) {
authorizedClientRepository = new TestOAuth2AuthorizedClientRepository(authorizedClientRepository);
OAuth2ClientServletTestUtils.setAuthorizedClientRepository(request, authorizedClientRepository);
@ -1668,11 +1665,10 @@ public final class SecurityMockMvcRequestPostProcessors {
this.delegate = delegate;
}
@NullUnmarked
@Override
public @Nullable OAuth2AuthorizedClient authorize(OAuth2AuthorizeRequest authorizeRequest) {
HttpServletRequest request = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
if (isEnabled(request)) {
if (this.authorizedClientRepository != null && isEnabled(request)) {
return this.authorizedClientRepository.loadAuthorizedClient(
authorizeRequest.getClientRegistrationId(), authorizeRequest.getPrincipal(), request);
}
@ -1683,9 +1679,8 @@ public final class SecurityMockMvcRequestPostProcessors {
request.setAttribute(ENABLED_ATTR_NAME, Boolean.TRUE);
}
@NullUnmarked
boolean isEnabled(@Nullable HttpServletRequest request) {
return Boolean.TRUE.equals(request.getAttribute(ENABLED_ATTR_NAME));
return request != null && Boolean.TRUE.equals(request.getAttribute(ENABLED_ATTR_NAME));
}
}
@ -1703,8 +1698,7 @@ public final class SecurityMockMvcRequestPostProcessors {
private final OAuth2AuthorizedClientRepository delegate;
@NullUnmarked
TestOAuth2AuthorizedClientRepository(@Nullable OAuth2AuthorizedClientRepository delegate) {
TestOAuth2AuthorizedClientRepository(OAuth2AuthorizedClientRepository delegate) {
this.delegate = delegate;
}

View File

@ -23,7 +23,6 @@ import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.security.authentication.AuthenticationTrustResolver;
@ -107,7 +106,6 @@ public final class SecurityMockMvcResultMatchers {
AuthenticatedMatcher() {
}
@NullUnmarked
@Override
public void match(MvcResult result) {
SecurityContext context = load(result);

View File

@ -21,10 +21,10 @@ import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.jspecify.annotations.NullUnmarked;
import org.springframework.security.config.BeanIds;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
@ -67,7 +67,6 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
builder.addFilters(this.delegateFilter);
}
@NullUnmarked
@Override
public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder,
WebApplicationContext context) {
@ -79,7 +78,9 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
() -> "springSecurityFilterChain cannot be null. Ensure a Bean with the name " + securityBeanId
+ " implementing Filter is present or inject the Filter to be used.");
// This is used by other test support to obtain the FilterChainProxy
context.getServletContext().setAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN, getSpringSecurityFilterChain());
ServletContext servletContext = context.getServletContext();
Assert.notNull(servletContext, "ServletContext must not be null");
servletContext.setAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN, getSpringSecurityFilterChain());
return testSecurityContext();
}

View File

@ -21,7 +21,6 @@ import java.util.List;
import jakarta.servlet.Filter;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@ -37,6 +36,7 @@ import org.springframework.security.web.csrf.CsrfTokenRequestHandler;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
@ -66,15 +66,19 @@ public abstract class WebTestUtils {
* @return the {@link SecurityContextRepository} for the specified
* {@link HttpServletRequest}
*/
@NullUnmarked
public static SecurityContextRepository getSecurityContextRepository(HttpServletRequest request) {
SecurityContextPersistenceFilter filter = findFilter(request, SecurityContextPersistenceFilter.class);
if (filter != null) {
return (SecurityContextRepository) ReflectionTestUtils.getField(filter, "repo");
SecurityContextRepository repo = (SecurityContextRepository) ReflectionTestUtils.getField(filter, "repo");
Assert.notNull(repo, "SecurityContextRepository must not be null");
return repo;
}
SecurityContextHolderFilter holderFilter = findFilter(request, SecurityContextHolderFilter.class);
if (holderFilter != null) {
return (SecurityContextRepository) ReflectionTestUtils.getField(holderFilter, "securityContextRepository");
SecurityContextRepository securityContextRepository = (SecurityContextRepository) ReflectionTestUtils
.getField(holderFilter, "securityContextRepository");
Assert.notNull(securityContextRepository, "SecurityContextRepository must not be null");
return securityContextRepository;
}
return DEFAULT_CONTEXT_REPO;
}

View File

@ -26,7 +26,6 @@ import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
@ -69,14 +68,14 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
return new ObservationWebFilterChain(wrapSecured(original)::filter, wrap(filters));
}
private static AroundWebFilterObservation observation(ServerWebExchange exchange) {
AroundWebFilterObservation observation = exchange.getAttribute(ATTRIBUTE);
return (observation != null) ? observation : AroundWebFilterObservation.NOOP;
private static @Nullable AroundWebFilterObservation observation(ServerWebExchange exchange) {
return exchange.getAttribute(ATTRIBUTE);
}
private WebFilterChain wrapSecured(WebFilterChain original) {
return (exchange) -> Mono.deferContextual((contextView) -> {
AroundWebFilterObservation parent = observation(exchange);
Assert.notNull(parent, "AroundWebFilterObservation parent cannot be null");
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
Observation observation = Observation.createNotStarted(SECURED_OBSERVATION_NAME, this.registry)
.contextualName("secured request")
@ -203,6 +202,7 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
private Mono<Void> wrapFilter(ServerWebExchange exchange, WebFilterChain chain) {
AroundWebFilterObservation parent = observation(exchange);
Assert.notNull(parent, "ObservationWebFilter parent is required");
if (parent.before().getContext() instanceof WebFilterChainObservationContext parentBefore) {
parentBefore.setChainSize(this.size);
parentBefore.setFilterName(this.name);
@ -575,7 +575,7 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
private final String filterSection;
@Nullable private String filterName;
private @Nullable String filterName;
private int chainPosition;

View File

@ -46,7 +46,6 @@ import com.webauthn4j.data.client.challenge.DefaultChallenge;
import com.webauthn4j.data.extension.authenticator.AuthenticationExtensionAuthenticatorOutput;
import com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput;
import com.webauthn4j.server.ServerProperty;
import org.jspecify.annotations.NullUnmarked;
import org.jspecify.annotations.Nullable;
import org.springframework.security.authentication.AuthenticationTrustResolver;
@ -358,7 +357,6 @@ public class Webauthn4JRelyingPartyOperations implements WebAuthnRelyingPartyOpe
.build();
}
@NullUnmarked
private List<CredentialRecord> findCredentialRecords(@Nullable Authentication authentication) {
if (!this.trustResolver.isAuthenticated(authentication)) {
return Collections.emptyList();