mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-10-22 18:28:51 +00:00
Enable Null checking in spring-security-web via JSpecify
Closes gh-17535
This commit is contained in:
parent
49f308adb0
commit
c2ba662b91
@ -367,7 +367,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filters: List<Filter> = filterChain.getFilters("/")
|
||||
val filters: List<Filter>? = filterChain.getFilters("/")
|
||||
|
||||
assertThat(filters).anyMatch { it is CustomFilter }
|
||||
}
|
||||
@ -390,7 +390,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterConfigReified::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filters: List<Filter> = filterChain.getFilters("/")
|
||||
val filters: List<Filter>? = filterChain.getFilters("/")
|
||||
|
||||
assertThat(filters).anyMatch { it is CustomFilter }
|
||||
}
|
||||
@ -413,7 +413,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterAfterConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filters: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filters: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filters).containsSubsequence(
|
||||
UsernamePasswordAuthenticationFilter::class.java,
|
||||
@ -440,7 +440,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterAfterConfigReified::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filterClasses).containsSubsequence(
|
||||
UsernamePasswordAuthenticationFilter::class.java,
|
||||
@ -467,7 +467,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterBeforeConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filters: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filters: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filters).containsSubsequence(
|
||||
CustomFilter::class.java,
|
||||
@ -494,7 +494,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomFilterBeforeConfigReified::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filterClasses).containsSubsequence(
|
||||
CustomFilter::class.java,
|
||||
@ -523,7 +523,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomSecurityConfigurerConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filterClasses).contains(
|
||||
CustomFilter::class.java
|
||||
@ -535,7 +535,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomSecurityConfigurerConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filterClasses).contains(
|
||||
CustomFilter::class.java
|
||||
@ -588,7 +588,7 @@ class HttpSecurityDslTests {
|
||||
this.spring.register(CustomDslUsingWithConfig::class.java).autowire()
|
||||
|
||||
val filterChain = spring.context.getBean(FilterChainProxy::class.java)
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/").map { it.javaClass }
|
||||
val filterClasses: List<Class<out Filter>> = filterChain.getFilters("/")!!.map { it.javaClass }
|
||||
|
||||
assertThat(filterClasses).contains(
|
||||
UsernamePasswordAuthenticationFilter::class.java
|
||||
|
@ -350,8 +350,8 @@ class LogoutDslTests {
|
||||
|
||||
class NoopLogoutHandler: LogoutHandler {
|
||||
override fun logout(
|
||||
request: HttpServletRequest?,
|
||||
response: HttpServletResponse?,
|
||||
request: HttpServletRequest,
|
||||
response: HttpServletResponse,
|
||||
authentication: Authentication?
|
||||
) { }
|
||||
|
||||
|
@ -132,8 +132,8 @@ class RequiresChannelDslTests {
|
||||
|
||||
companion object {
|
||||
val CHANNEL_PROCESSOR: ChannelProcessor = object : ChannelProcessor {
|
||||
override fun decide(invocation: FilterInvocation?, config: MutableCollection<ConfigAttribute>?) {}
|
||||
override fun supports(attribute: ConfigAttribute?): Boolean = true
|
||||
override fun decide(invocation: FilterInvocation, config: MutableCollection<ConfigAttribute>) {}
|
||||
override fun supports(attribute: ConfigAttribute): Boolean = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ class SecurityContextDslTests {
|
||||
testContext.autowire()
|
||||
val filterChainProxy = testContext.context.getBean(FilterChainProxy::class.java)
|
||||
// @formatter:off
|
||||
val filterTypes = filterChainProxy.getFilters("/").toList()
|
||||
val filterTypes = filterChainProxy.getFilters("/")!!.toList()
|
||||
|
||||
assertThat(filterTypes)
|
||||
.anyMatch { it is SecurityContextHolderFilter }
|
||||
|
@ -270,8 +270,8 @@ class ServerHttpBasicDslTests {
|
||||
|
||||
open class MockServerAuthenticationFailureHandler: ServerAuthenticationFailureHandler {
|
||||
override fun onAuthenticationFailure(
|
||||
webFilterExchange: WebFilterExchange?,
|
||||
exception: AuthenticationException?
|
||||
webFilterExchange: WebFilterExchange,
|
||||
exception: AuthenticationException
|
||||
): Mono<Void> {
|
||||
return Mono.empty()
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.access;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
|
||||
import org.springframework.security.access.intercept.RunAsManager;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.annotation.SecurityAnnotationScanner;
|
||||
@ -45,6 +47,7 @@ import org.springframework.security.core.annotation.SecurityAnnotationScanner;
|
||||
* {@link AuthorizationManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
@NullUnmarked
|
||||
public interface ConfigAttribute extends Serializable {
|
||||
|
||||
/**
|
||||
|
@ -177,7 +177,7 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat
|
||||
this.trustResolver = trustResolver;
|
||||
}
|
||||
|
||||
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
|
||||
public void setRoleHierarchy(@Nullable RoleHierarchy roleHierarchy) {
|
||||
this.roleHierarchy = roleHierarchy;
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // FIXME: Dataflow analysis limitation
|
||||
public EvaluationContext createEvaluationContext(Supplier<? extends @Nullable Authentication> authentication,
|
||||
MethodInvocation mi) {
|
||||
MethodSecurityExpressionOperations root = createSecurityExpressionRoot(authentication, mi);
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.access.vote;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -53,6 +55,7 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
@NullUnmarked
|
||||
public class RoleVoter implements AccessDecisionVoter<Object> {
|
||||
|
||||
private String rolePrefix = "ROLE_";
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.authentication;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
@ -80,6 +81,7 @@ public interface AuthenticationTrustResolver {
|
||||
* {@link Authentication#isAuthenticated()} is true.
|
||||
* @since 6.1.7
|
||||
*/
|
||||
@Contract("null -> false")
|
||||
default boolean isAuthenticated(@Nullable Authentication authentication) {
|
||||
return authentication != null && authentication.isAuthenticated() && !isAnonymous(authentication);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationT
|
||||
|
||||
private static final long serialVersionUID = 620L;
|
||||
|
||||
private final Object principal;
|
||||
private final @Nullable Object principal;
|
||||
|
||||
private @Nullable Object credentials;
|
||||
|
||||
@ -49,7 +49,7 @@ public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationT
|
||||
* will return <code>false</code>.
|
||||
*
|
||||
*/
|
||||
public UsernamePasswordAuthenticationToken(Object principal, @Nullable Object credentials) {
|
||||
public UsernamePasswordAuthenticationToken(@Nullable Object principal, @Nullable Object credentials) {
|
||||
super(null);
|
||||
this.principal = principal;
|
||||
this.credentials = credentials;
|
||||
@ -82,7 +82,8 @@ public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationT
|
||||
*
|
||||
* @since 5.7
|
||||
*/
|
||||
public static UsernamePasswordAuthenticationToken unauthenticated(Object principal, @Nullable Object credentials) {
|
||||
public static UsernamePasswordAuthenticationToken unauthenticated(@Nullable Object principal,
|
||||
@Nullable Object credentials) {
|
||||
return new UsernamePasswordAuthenticationToken(principal, credentials);
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationT
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
public @Nullable Object getPrincipal() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
|
@ -178,8 +178,10 @@ public abstract class AbstractJaasAuthenticationProvider implements Authenticati
|
||||
// applied.
|
||||
authorities = getAuthorities(principals);
|
||||
// Convert the authorities set back to an array and apply it to the token.
|
||||
JaasAuthenticationToken result = new JaasAuthenticationToken(request.getPrincipal(),
|
||||
request.getCredentials(), new ArrayList<>(authorities), loginContext);
|
||||
Object principal = request.getPrincipal();
|
||||
Assert.notNull(principal, "The principal cannot be null");
|
||||
JaasAuthenticationToken result = new JaasAuthenticationToken(principal, request.getCredentials(),
|
||||
new ArrayList<>(authorities), loginContext);
|
||||
// Publish the success event
|
||||
publishSuccessEvent(result);
|
||||
// we're done, return the token.
|
||||
|
@ -71,8 +71,8 @@ public class OneTimeTokenAuthenticationToken extends AbstractAuthenticationToken
|
||||
* @deprecated Please use constructor that takes a {@link String} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "7.0")
|
||||
public static OneTimeTokenAuthenticationToken unauthenticated(String tokenValue) {
|
||||
return new OneTimeTokenAuthenticationToken(null, tokenValue);
|
||||
public static OneTimeTokenAuthenticationToken unauthenticated(@Nullable String tokenValue) {
|
||||
return new OneTimeTokenAuthenticationToken(null, (tokenValue != null) ? tokenValue : "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.authorization;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -46,6 +48,7 @@ public interface AuthorizationEventPublisher {
|
||||
* @param <T> the secured object's type
|
||||
* @since 6.4
|
||||
*/
|
||||
<T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object, AuthorizationResult result);
|
||||
<T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||
@Nullable AuthorizationResult result);
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package org.springframework.security.authorization;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
||||
@ -57,7 +59,7 @@ public final class SpringAuthorizationEventPublisher implements AuthorizationEve
|
||||
*/
|
||||
@Override
|
||||
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||
AuthorizationResult result) {
|
||||
@Nullable AuthorizationResult result) {
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public final class MethodExpressionAuthorizationManager implements Authorization
|
||||
* expression
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // FIXME: Dataflow analysis limitation
|
||||
public AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
|
||||
MethodInvocation context) {
|
||||
EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, context);
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.authorization.method;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -32,7 +34,7 @@ final class NoOpAuthorizationEventPublisher implements AuthorizationEventPublish
|
||||
|
||||
@Override
|
||||
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||
AuthorizationResult result) {
|
||||
@Nullable AuthorizationResult result) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ public abstract class AuthenticationException extends RuntimeException {
|
||||
* authentication attempt
|
||||
* @since 6.5
|
||||
*/
|
||||
public void setAuthenticationRequest(Authentication authenticationRequest) {
|
||||
public void setAuthenticationRequest(@Nullable Authentication authenticationRequest) {
|
||||
Assert.notNull(authenticationRequest, "authenticationRequest cannot be null");
|
||||
this.authenticationRequest = authenticationRequest;
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
plugins {
|
||||
id 'security-nullability'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.spring-module'
|
||||
|
||||
configurations {
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@ -51,9 +52,9 @@ public final class DefaultSecurityFilterChain implements SecurityFilterChain, Be
|
||||
|
||||
private final List<Filter> filters;
|
||||
|
||||
private String beanName;
|
||||
private @Nullable String beanName;
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
private @Nullable ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
|
||||
this(requestMatcher, Arrays.asList(filters));
|
||||
|
@ -30,6 +30,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -164,6 +165,7 @@ public class FilterChainProxy extends GenericFilterBean {
|
||||
private FilterChainDecorator filterChainDecorator = new VirtualFilterChainDecorator();
|
||||
|
||||
public FilterChainProxy() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
|
||||
public FilterChainProxy(SecurityFilterChain chain) {
|
||||
@ -171,6 +173,7 @@ public class FilterChainProxy extends GenericFilterBean {
|
||||
}
|
||||
|
||||
public FilterChainProxy(List<SecurityFilterChain> filterChains) {
|
||||
Assert.notNull(filterChains, "filterChains cannot be null");
|
||||
this.filterChains = filterChains;
|
||||
}
|
||||
|
||||
@ -239,7 +242,7 @@ public class FilterChainProxy extends GenericFilterBean {
|
||||
* @param request the request to match
|
||||
* @return an ordered array of Filters defining the filter chain
|
||||
*/
|
||||
private List<Filter> getFilters(HttpServletRequest request) {
|
||||
private @Nullable List<Filter> getFilters(HttpServletRequest request) {
|
||||
int count = 0;
|
||||
for (SecurityFilterChain chain : this.filterChains) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
@ -258,7 +261,7 @@ public class FilterChainProxy extends GenericFilterBean {
|
||||
* @param url the URL
|
||||
* @return matching filter list
|
||||
*/
|
||||
public List<Filter> getFilters(String url) {
|
||||
public @Nullable List<Filter> getFilters(String url) {
|
||||
PathPatternRequestTransformer requestTransformer = new PathPatternRequestTransformer();
|
||||
HttpServletRequest transformed = requestTransformer.transform(new FilterInvocation(url, "GET").getRequest());
|
||||
return getFilters(this.firewall.getFirewalledRequest(transformed));
|
||||
|
@ -36,6 +36,7 @@ import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
@ -62,11 +63,11 @@ public class FilterInvocation {
|
||||
throw new UnsupportedOperationException("Dummy filter chain");
|
||||
};
|
||||
|
||||
private FilterChain chain;
|
||||
private final FilterChain chain;
|
||||
|
||||
private HttpServletRequest request;
|
||||
|
||||
private HttpServletResponse response;
|
||||
private @Nullable HttpServletResponse response;
|
||||
|
||||
public FilterInvocation(ServletRequest request, ServletResponse response, FilterChain chain) {
|
||||
Assert.isTrue(request != null && response != null && chain != null, "Cannot pass null values to constructor");
|
||||
@ -79,11 +80,12 @@ public class FilterInvocation {
|
||||
this(null, servletPath, method);
|
||||
}
|
||||
|
||||
public FilterInvocation(String contextPath, String servletPath, String method) {
|
||||
public FilterInvocation(@Nullable String contextPath, String servletPath, String method) {
|
||||
this(contextPath, servletPath, method, null);
|
||||
}
|
||||
|
||||
public FilterInvocation(String contextPath, String servletPath, String method, ServletContext servletContext) {
|
||||
public FilterInvocation(@Nullable String contextPath, String servletPath, @Nullable String method,
|
||||
@Nullable ServletContext servletContext) {
|
||||
this(contextPath, servletPath, null, null, method, servletContext);
|
||||
}
|
||||
|
||||
@ -91,8 +93,8 @@ public class FilterInvocation {
|
||||
this(contextPath, servletPath, pathInfo, query, method, null);
|
||||
}
|
||||
|
||||
public FilterInvocation(String contextPath, String servletPath, String pathInfo, String query, String method,
|
||||
ServletContext servletContext) {
|
||||
public FilterInvocation(@Nullable String contextPath, String servletPath, @Nullable String pathInfo,
|
||||
@Nullable String query, @Nullable String method, @Nullable ServletContext servletContext) {
|
||||
DummyRequest request = new DummyRequest();
|
||||
contextPath = (contextPath != null) ? contextPath : "/cp";
|
||||
request.setContextPath(contextPath);
|
||||
@ -103,6 +105,7 @@ public class FilterInvocation {
|
||||
request.setMethod(method);
|
||||
request.setServletContext(servletContext);
|
||||
this.request = request;
|
||||
this.chain = DUMMY_CHAIN;
|
||||
}
|
||||
|
||||
public FilterChain getChain() {
|
||||
@ -124,7 +127,7 @@ public class FilterInvocation {
|
||||
return this.request;
|
||||
}
|
||||
|
||||
public HttpServletResponse getHttpResponse() {
|
||||
public @Nullable HttpServletResponse getHttpResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@ -140,7 +143,7 @@ public class FilterInvocation {
|
||||
return getHttpRequest();
|
||||
}
|
||||
|
||||
public HttpServletResponse getResponse() {
|
||||
public @Nullable HttpServletResponse getResponse() {
|
||||
return getHttpResponse();
|
||||
}
|
||||
|
||||
@ -160,19 +163,19 @@ public class FilterInvocation {
|
||||
DummyRequest.class.getClassLoader(), new Class[] { HttpServletRequest.class },
|
||||
new UnsupportedOperationExceptionInvocationHandler());
|
||||
|
||||
private String requestURI;
|
||||
private @Nullable String requestURI;
|
||||
|
||||
private String contextPath = "";
|
||||
|
||||
private String servletPath;
|
||||
private @Nullable String servletPath;
|
||||
|
||||
private String pathInfo;
|
||||
private @Nullable String pathInfo;
|
||||
|
||||
private String queryString;
|
||||
private @Nullable String queryString;
|
||||
|
||||
private String method;
|
||||
private @Nullable String method;
|
||||
|
||||
private ServletContext servletContext;
|
||||
private @Nullable ServletContext servletContext;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
@ -188,7 +191,7 @@ public class FilterInvocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String attributeName) {
|
||||
public @Nullable Object getAttribute(String attributeName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -196,12 +199,12 @@ public class FilterInvocation {
|
||||
this.requestURI = requestURI;
|
||||
}
|
||||
|
||||
void setPathInfo(String pathInfo) {
|
||||
void setPathInfo(@Nullable String pathInfo) {
|
||||
this.pathInfo = pathInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestURI() {
|
||||
public @Nullable String getRequestURI() {
|
||||
return this.requestURI;
|
||||
}
|
||||
|
||||
@ -219,40 +222,40 @@ public class FilterInvocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletPath() {
|
||||
public @Nullable String getServletPath() {
|
||||
return this.servletPath;
|
||||
}
|
||||
|
||||
void setMethod(String method) {
|
||||
void setMethod(@Nullable String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
public @Nullable String getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathInfo() {
|
||||
public @Nullable String getPathInfo() {
|
||||
return this.pathInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryString() {
|
||||
public @Nullable String getQueryString() {
|
||||
return this.queryString;
|
||||
}
|
||||
|
||||
void setQueryString(String queryString) {
|
||||
void setQueryString(@Nullable String queryString) {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
public @Nullable String getServerName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
public @Nullable String getHeader(String name) {
|
||||
return this.headers.getFirst(name);
|
||||
}
|
||||
|
||||
@ -284,7 +287,7 @@ public class FilterInvocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
public @Nullable String getParameter(String name) {
|
||||
String[] array = this.parameters.get(name);
|
||||
return (array != null && array.length > 0) ? array[0] : null;
|
||||
}
|
||||
@ -300,7 +303,7 @@ public class FilterInvocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
public String @Nullable [] getParameterValues(String name) {
|
||||
return this.parameters.get(name);
|
||||
}
|
||||
|
||||
@ -309,11 +312,11 @@ public class FilterInvocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
public @Nullable ServletContext getServletContext() {
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
void setServletContext(ServletContext servletContext) {
|
||||
void setServletContext(@Nullable ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -49,6 +51,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Nikita Konev
|
||||
* @since 6.0
|
||||
*/
|
||||
@NullUnmarked // https://github.com/spring-projects/spring-security/issues/17815
|
||||
public final class ObservationFilterChainDecorator implements FilterChainProxy.FilterChainDecorator {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FilterChainProxy.class);
|
||||
@ -507,7 +510,7 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
|
||||
|
||||
private final String filterSection;
|
||||
|
||||
private String filterName;
|
||||
private @Nullable String filterName;
|
||||
|
||||
private int chainPosition;
|
||||
|
||||
@ -530,7 +533,7 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
|
||||
return this.filterSection;
|
||||
}
|
||||
|
||||
String getFilterName() {
|
||||
@Nullable String getFilterName() {
|
||||
return this.filterName;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* <code>PortMapper</code> implementations provide callers with information about which
|
||||
* HTTP ports are associated with which HTTPS ports on the system, and vice versa.
|
||||
@ -32,7 +34,7 @@ public interface PortMapper {
|
||||
* @param httpsPort
|
||||
* @return the HTTP port or <code>null</code> if unknown
|
||||
*/
|
||||
Integer lookupHttpPort(Integer httpsPort);
|
||||
@Nullable Integer lookupHttpPort(Integer httpsPort);
|
||||
|
||||
/**
|
||||
* Locates the HTTPS port associated with the specified HTTP port.
|
||||
@ -42,6 +44,6 @@ public interface PortMapper {
|
||||
* @param httpPort
|
||||
* @return the HTTPS port or <code>null</code> if unknown
|
||||
*/
|
||||
Integer lookupHttpsPort(Integer httpPort);
|
||||
@Nullable Integer lookupHttpsPort(Integer httpPort);
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package org.springframework.security.web;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@ -50,7 +52,7 @@ public class PortMapperImpl implements PortMapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer lookupHttpPort(Integer httpsPort) {
|
||||
public @Nullable Integer lookupHttpPort(Integer httpsPort) {
|
||||
for (Integer httpPort : this.httpsPortMappings.keySet()) {
|
||||
if (this.httpsPortMappings.get(httpPort).equals(httpsPort)) {
|
||||
return httpPort;
|
||||
@ -60,7 +62,7 @@ public class PortMapperImpl implements PortMapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer lookupHttpsPort(Integer httpPort) {
|
||||
public @Nullable Integer lookupHttpsPort(Integer httpPort) {
|
||||
return this.httpsPortMappings.get(httpPort);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web;
|
||||
import java.util.Locale;
|
||||
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@ -54,7 +55,7 @@ public class PortResolverImpl implements PortResolver {
|
||||
return (mappedPort != null) ? mappedPort : serverPort;
|
||||
}
|
||||
|
||||
private Integer getMappedPort(int serverPort, String scheme) {
|
||||
private @Nullable Integer getMappedPort(int serverPort, String scheme) {
|
||||
if ("http".equals(scheme)) {
|
||||
return this.portMapper.lookupHttpPort(serverPort);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -47,7 +48,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(AccessDeniedHandlerImpl.class);
|
||||
|
||||
private String errorPage;
|
||||
private @Nullable String errorPage;
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.access;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
@ -38,7 +39,7 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
|
||||
|
||||
private final AuthorizationManager<HttpServletRequest> authorizationManager;
|
||||
|
||||
private ServletContext servletContext;
|
||||
private @Nullable ServletContext servletContext;
|
||||
|
||||
private HttpServletRequestTransformer requestTransformer = HttpServletRequestTransformer.IDENTITY;
|
||||
|
||||
@ -54,7 +55,8 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
|
||||
public boolean isAllowed(@Nullable String contextPath, String uri, @Nullable String method,
|
||||
Authentication authentication) {
|
||||
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
|
||||
HttpServletRequest httpRequest = this.requestTransformer.transform(filterInvocation.getHttpRequest());
|
||||
AuthorizationResult result = this.authorizationManager.authorize(() -> authentication, httpRequest);
|
||||
|
@ -21,6 +21,7 @@ import java.util.Collection;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
@ -46,7 +47,7 @@ public class DefaultWebInvocationPrivilegeEvaluator implements WebInvocationPriv
|
||||
|
||||
private final AbstractSecurityInterceptor securityInterceptor;
|
||||
|
||||
private ServletContext servletContext;
|
||||
private @Nullable ServletContext servletContext;
|
||||
|
||||
public DefaultWebInvocationPrivilegeEvaluator(AbstractSecurityInterceptor securityInterceptor) {
|
||||
Assert.notNull(securityInterceptor, "SecurityInterceptor cannot be null");
|
||||
@ -86,7 +87,8 @@ public class DefaultWebInvocationPrivilegeEvaluator implements WebInvocationPriv
|
||||
* @return true if access is allowed, false if denied
|
||||
*/
|
||||
@Override
|
||||
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
|
||||
public boolean isAllowed(@Nullable String contextPath, String uri, @Nullable String method,
|
||||
Authentication authentication) {
|
||||
Assert.notNull(uri, "uri parameter is required");
|
||||
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
|
||||
Collection<ConfigAttribute> attributes = this.securityInterceptor.obtainSecurityMetadataSource()
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
@ -169,7 +170,7 @@ public class ExceptionTranslationFilter extends GenericFilterBean implements Mes
|
||||
}
|
||||
|
||||
private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain chain, RuntimeException exception) throws IOException, ServletException {
|
||||
FilterChain chain, @Nullable RuntimeException exception) throws IOException, ServletException {
|
||||
if (exception instanceof AuthenticationException) {
|
||||
handleAuthenticationException(request, response, chain, (AuthenticationException) exception);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
|
||||
import org.springframework.web.util.ServletRequestPathUtils;
|
||||
@ -51,7 +52,7 @@ public final class PathPatternRequestTransformer
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name) {
|
||||
public @Nullable Object getAttribute(String name) {
|
||||
return this.attributes.get(name);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -46,7 +47,7 @@ public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator
|
||||
|
||||
private final List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> delegates;
|
||||
|
||||
private ServletContext servletContext;
|
||||
private @Nullable ServletContext servletContext;
|
||||
|
||||
public RequestMatcherDelegatingWebInvocationPrivilegeEvaluator(
|
||||
List<RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>>> requestMatcherPrivilegeEvaluatorsEntries) {
|
||||
@ -119,7 +120,8 @@ public final class RequestMatcherDelegatingWebInvocationPrivilegeEvaluator
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<WebInvocationPrivilegeEvaluator> getDelegate(String contextPath, String uri, String method) {
|
||||
private List<WebInvocationPrivilegeEvaluator> getDelegate(@Nullable String contextPath, String uri,
|
||||
@Nullable String method) {
|
||||
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
|
||||
HttpServletRequest request = filterInvocation.getHttpRequest();
|
||||
for (RequestMatcherEntry<List<WebInvocationPrivilegeEvaluator>> delegate : this.delegates) {
|
||||
|
@ -22,6 +22,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
@ -79,7 +80,7 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
|
||||
this.redirectStrategy.sendRedirect(request, response, redirectUrl);
|
||||
}
|
||||
|
||||
protected abstract Integer getMappedPort(Integer mapFromPort);
|
||||
protected abstract @Nullable Integer getMappedPort(Integer mapFromPort);
|
||||
|
||||
protected final PortMapper getPortMapper() {
|
||||
return this.portMapper;
|
||||
|
@ -22,6 +22,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
@ -49,6 +51,7 @@ import org.springframework.util.Assert;
|
||||
* {@link RequestMatcher} for any sophisticated decision-making
|
||||
*/
|
||||
@Deprecated
|
||||
@NullUnmarked
|
||||
public class ChannelDecisionManagerImpl implements ChannelDecisionManager, InitializingBean {
|
||||
|
||||
public static final String ANY_CHANNEL = "ANY_CHANNEL";
|
||||
@ -76,7 +79,7 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager, Initi
|
||||
}
|
||||
}
|
||||
|
||||
protected List<ChannelProcessor> getChannelProcessors() {
|
||||
protected @Nullable List<ChannelProcessor> getChannelProcessors() {
|
||||
return this.channelProcessors;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
@ -88,8 +89,10 @@ import org.springframework.web.filter.GenericFilterBean;
|
||||
@Deprecated
|
||||
public class ChannelProcessingFilter extends GenericFilterBean {
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ChannelDecisionManager channelDecisionManager;
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private FilterInvocationSecurityMetadataSource securityMetadataSource;
|
||||
|
||||
@Override
|
||||
@ -128,14 +131,16 @@ public class ChannelProcessingFilter extends GenericFilterBean {
|
||||
if (attributes != null) {
|
||||
this.logger.debug(LogMessage.format("Request: %s; ConfigAttributes: %s", filterInvocation, attributes));
|
||||
this.channelDecisionManager.decide(filterInvocation, attributes);
|
||||
if (filterInvocation.getResponse().isCommitted()) {
|
||||
@Nullable HttpServletResponse channelResponse = filterInvocation.getResponse();
|
||||
Assert.notNull(channelResponse, "HttpServletResponse is required");
|
||||
if (channelResponse.isCommitted()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
protected ChannelDecisionManager getChannelDecisionManager() {
|
||||
protected @Nullable ChannelDecisionManager getChannelDecisionManager() {
|
||||
return this.channelDecisionManager;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
@ -63,7 +65,9 @@ public class InsecureChannelProcessor implements InitializingBean, ChannelProces
|
||||
for (ConfigAttribute attribute : config) {
|
||||
if (supports(attribute)) {
|
||||
if (invocation.getHttpRequest().isSecure()) {
|
||||
this.entryPoint.commence(invocation.getRequest(), invocation.getResponse());
|
||||
@Nullable HttpServletResponse response = invocation.getResponse();
|
||||
Assert.notNull(response, "HttpServletResponse required");
|
||||
this.entryPoint.commence(invocation.getRequest(), response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.access.channel;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.web.PortMapper;
|
||||
|
||||
/**
|
||||
@ -38,7 +40,7 @@ public class RetryWithHttpEntryPoint extends AbstractRetryEntryPoint {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getMappedPort(Integer mapFromPort) {
|
||||
protected @Nullable Integer getMappedPort(Integer mapFromPort) {
|
||||
return getPortMapper().lookupHttpPort(mapFromPort);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.access.channel;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.web.PortMapper;
|
||||
|
||||
/**
|
||||
@ -39,7 +41,7 @@ public class RetryWithHttpsEntryPoint extends AbstractRetryEntryPoint {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getMappedPort(Integer mapFromPort) {
|
||||
protected @Nullable Integer getMappedPort(Integer mapFromPort) {
|
||||
return getPortMapper().lookupHttpsPort(mapFromPort);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
@ -63,7 +64,9 @@ public class SecureChannelProcessor implements InitializingBean, ChannelProcesso
|
||||
for (ConfigAttribute attribute : config) {
|
||||
if (supports(attribute)) {
|
||||
if (!invocation.getHttpRequest().isSecure()) {
|
||||
this.entryPoint.commence(invocation.getRequest(), invocation.getResponse());
|
||||
HttpServletResponse response = invocation.getResponse();
|
||||
Assert.notNull(response, "HttpServletResponse is required");
|
||||
this.entryPoint.commence(invocation.getRequest(), response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,4 +19,7 @@
|
||||
* <p>
|
||||
* Most commonly used to enforce that requests are submitted over HTTP or HTTPS.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.access.channel;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web.access.expression;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
@ -53,7 +54,7 @@ abstract class AbstractVariableEvaluationContextPostProcessor
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private Map<String, String> variables;
|
||||
private @Nullable Map<String, String> variables;
|
||||
|
||||
VariableEvaluationContext(EvaluationContext delegate, HttpServletRequest request) {
|
||||
super(delegate);
|
||||
@ -61,7 +62,7 @@ abstract class AbstractVariableEvaluationContextPostProcessor
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookupVariable(String name) {
|
||||
public @Nullable Object lookupVariable(String name) {
|
||||
Object result = super.lookupVariable(name);
|
||||
if (result != null) {
|
||||
return result;
|
||||
|
@ -46,6 +46,7 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
|
||||
private String defaultRolePrefix = "ROLE_";
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // https://github.com/spring-projects/spring-framework/issues/35371
|
||||
public EvaluationContext createEvaluationContext(Supplier<? extends @Nullable Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
WebSecurityExpressionRoot root = createSecurityExpressionRoot(authentication, context);
|
||||
@ -56,13 +57,13 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
return createSecurityExpressionRoot(() -> authentication, context);
|
||||
}
|
||||
|
||||
private WebSecurityExpressionRoot createSecurityExpressionRoot(Supplier<? extends Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
private WebSecurityExpressionRoot createSecurityExpressionRoot(
|
||||
Supplier<? extends @Nullable Authentication> authentication, RequestAuthorizationContext context) {
|
||||
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, context.getRequest());
|
||||
root.setRoleHierarchy(getRoleHierarchy());
|
||||
root.setPermissionEvaluator(getPermissionEvaluator());
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.access.expression;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.access.expression.AbstractSecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.SecurityExpressionOperations;
|
||||
@ -38,7 +40,7 @@ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpress
|
||||
private String defaultRolePrefix = "ROLE_";
|
||||
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication,
|
||||
FilterInvocation fi) {
|
||||
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
|
||||
root.setPermissionEvaluator(getPermissionEvaluator());
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.web.access.expression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.ConstructorResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
@ -84,17 +86,17 @@ class DelegatingEvaluationContext implements EvaluationContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanResolver getBeanResolver() {
|
||||
public @Nullable BeanResolver getBeanResolver() {
|
||||
return this.delegate.getBeanResolver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVariable(String name, Object value) {
|
||||
public void setVariable(String name, @Nullable Object value) {
|
||||
this.delegate.setVariable(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookupVariable(String name) {
|
||||
public @Nullable Object lookupVariable(String name) {
|
||||
return this.delegate.lookupVariable(name);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.access.expression;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
@ -32,6 +34,7 @@ import org.springframework.security.web.FilterInvocation;
|
||||
* {@link AuthorizationManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
@NullUnmarked
|
||||
class WebExpressionConfigAttribute implements ConfigAttribute, EvaluationContextPostProcessor<FilterInvocation> {
|
||||
|
||||
private final Expression authorizeExpression;
|
||||
|
@ -20,6 +20,7 @@ import java.util.Collection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
@ -66,7 +67,7 @@ public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation>
|
||||
return ACCESS_DENIED;
|
||||
}
|
||||
|
||||
private WebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
|
||||
private @Nullable WebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
|
||||
for (ConfigAttribute attribute : attributes) {
|
||||
if (attribute instanceof WebExpressionConfigAttribute) {
|
||||
return (WebExpressionConfigAttribute) attribute;
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web.access.expression;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -37,7 +38,7 @@ public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
|
||||
*/
|
||||
public final HttpServletRequest request;
|
||||
|
||||
public WebSecurityExpressionRoot(Authentication a, FilterInvocation fi) {
|
||||
public WebSecurityExpressionRoot(@Nullable Authentication a, FilterInvocation fi) {
|
||||
this(() -> a, fi.getRequest());
|
||||
}
|
||||
|
||||
@ -48,7 +49,9 @@ public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
|
||||
* @param request the {@link HttpServletRequest} to use
|
||||
* @since 5.8
|
||||
*/
|
||||
public WebSecurityExpressionRoot(Supplier<? extends Authentication> authentication, HttpServletRequest request) {
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1246
|
||||
public WebSecurityExpressionRoot(Supplier<? extends @Nullable Authentication> authentication,
|
||||
HttpServletRequest request) {
|
||||
super(authentication);
|
||||
this.request = request;
|
||||
}
|
||||
|
@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Implementation of web security expressions.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.access.expression;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -26,6 +26,7 @@ import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
@ -202,7 +203,7 @@ public class AuthorizationFilter extends GenericFilterBean {
|
||||
|
||||
@Override
|
||||
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||
AuthorizationResult result) {
|
||||
@Nullable AuthorizationResult result) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.access.intercept;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -99,7 +100,7 @@ public class DefaultFilterInvocationSecurityMetadataSource implements FilterInvo
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.FilterConfig;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.access.SecurityMetadataSource;
|
||||
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
|
||||
@ -48,7 +49,7 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
|
||||
|
||||
private static final String FILTER_APPLIED = "__spring_security_filterSecurityInterceptor_filterApplied";
|
||||
|
||||
private FilterInvocationSecurityMetadataSource securityMetadataSource;
|
||||
private @Nullable FilterInvocationSecurityMetadataSource securityMetadataSource;
|
||||
|
||||
private boolean observeOncePerRequest = false;
|
||||
|
||||
@ -83,12 +84,12 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
|
||||
invoke(new FilterInvocation(request, response, chain));
|
||||
}
|
||||
|
||||
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
|
||||
public @Nullable FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
|
||||
return this.securityMetadataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityMetadataSource obtainSecurityMetadataSource() {
|
||||
public @Nullable SecurityMetadataSource obtainSecurityMetadataSource() {
|
||||
return this.securityMetadataSource;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.access.intercept;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@ -26,13 +28,13 @@ public class RequestKey {
|
||||
|
||||
private final String url;
|
||||
|
||||
private final String method;
|
||||
private final @Nullable String method;
|
||||
|
||||
public RequestKey(String url) {
|
||||
this(url, null);
|
||||
}
|
||||
|
||||
public RequestKey(String url, String method) {
|
||||
public RequestKey(String url, @Nullable String method) {
|
||||
Assert.notNull(url, "url cannot be null");
|
||||
this.url = url;
|
||||
this.method = method;
|
||||
@ -42,7 +44,7 @@ public class RequestKey {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
String getMethod() {
|
||||
@Nullable String getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public final class RequestMatcherDelegatingAuthorizationManager implements Autho
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
|
||||
public @Nullable AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
|
||||
HttpServletRequest request) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace(LogMessage.format("Authorizing %s", requestLine(request)));
|
||||
|
@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Enforcement of security for HTTP requests, typically by the URL requested.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.access.intercept;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Access-control related classes and packages.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.access;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.web.aot.hint;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
@ -33,7 +35,7 @@ import org.springframework.security.web.access.expression.WebSecurityExpressionR
|
||||
class WebMvcSecurityRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
hints.reflection()
|
||||
.registerType(WebSecurityExpressionRoot.class, (builder) -> builder
|
||||
.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS));
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runtime hints for AOT web package.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.aot.hint;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -24,6 +24,7 @@ import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@ -120,7 +121,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
|
||||
protected ApplicationEventPublisher eventPublisher;
|
||||
@Nullable protected ApplicationEventPublisher eventPublisher;
|
||||
|
||||
protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||
|
||||
@ -129,6 +130,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
"Please either configure an AuthenticationConverter or override attemptAuthentication when extending AbstractAuthenticationProcessingFilter");
|
||||
};
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
@ -155,7 +157,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
* @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
|
||||
*/
|
||||
protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
|
||||
setFilterProcessesUrl(defaultFilterProcessesUrl);
|
||||
this(pathPattern(defaultFilterProcessesUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,7 +179,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
*/
|
||||
protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl,
|
||||
AuthenticationManager authenticationManager) {
|
||||
setFilterProcessesUrl(defaultFilterProcessesUrl);
|
||||
this(pathPattern(defaultFilterProcessesUrl));
|
||||
setAuthenticationManager(authenticationManager);
|
||||
}
|
||||
|
||||
@ -305,7 +307,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
||||
* @return the authenticated user token, or null if authentication is incomplete.
|
||||
* @throws AuthenticationException if authentication fails.
|
||||
*/
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
public @Nullable Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, IOException, ServletException {
|
||||
Authentication authentication = this.authenticationConverter.convert(request);
|
||||
if (authentication == null) {
|
||||
|
@ -23,6 +23,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -62,7 +63,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private String targetUrlParameter = null;
|
||||
private @Nullable String targetUrlParameter = null;
|
||||
|
||||
private String defaultTargetUrl = "/";
|
||||
|
||||
@ -81,8 +82,8 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
* <p>
|
||||
* The redirect will not be performed if the response has already been committed.
|
||||
*/
|
||||
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
protected void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException, ServletException {
|
||||
String targetUrl = determineTargetUrl(request, response, authentication);
|
||||
if (response.isCommitted()) {
|
||||
this.logger.debug(LogMessage.format("Did not redirect to %s since response already committed.", targetUrl));
|
||||
@ -96,7 +97,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
* @since 5.2
|
||||
*/
|
||||
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authentication) {
|
||||
@Nullable Authentication authentication) {
|
||||
return determineTargetUrl(request, response);
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
return this.defaultTargetUrl;
|
||||
}
|
||||
|
||||
private String getTargetUrlParameterValue(HttpServletRequest request) {
|
||||
private @Nullable String getTargetUrlParameterValue(HttpServletRequest request) {
|
||||
if (this.targetUrlParameter == null) {
|
||||
return null;
|
||||
}
|
||||
@ -133,7 +134,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
return this.defaultTargetUrl;
|
||||
}
|
||||
|
||||
private void trace(String msg, String... msgParts) {
|
||||
private void trace(String msg, @Nullable String... msgParts) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace(LogMessage.format(msg, msgParts));
|
||||
}
|
||||
@ -189,7 +190,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
||||
this.targetUrlParameter = targetUrlParameter;
|
||||
}
|
||||
|
||||
protected String getTargetUrlParameter() {
|
||||
protected @Nullable String getTargetUrlParameter() {
|
||||
return this.targetUrlParameter;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -35,6 +36,6 @@ import org.springframework.security.core.AuthenticationException;
|
||||
*/
|
||||
public interface AuthenticationConverter {
|
||||
|
||||
Authentication convert(HttpServletRequest request);
|
||||
@Nullable Authentication convert(HttpServletRequest request);
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
@ -218,7 +219,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
||||
this.successHandler.onAuthenticationSuccess(request, response, chain, authentication);
|
||||
}
|
||||
|
||||
private Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
private @Nullable Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, ServletException {
|
||||
Authentication authentication = this.authenticationConverter.convert(request);
|
||||
if (authentication == null) {
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web.authentication;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
@ -46,7 +47,7 @@ public final class DelegatingAuthenticationConverter implements AuthenticationCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication convert(HttpServletRequest request) {
|
||||
public @Nullable Authentication convert(HttpServletRequest request) {
|
||||
for (AuthenticationConverter delegate : this.delegates) {
|
||||
Authentication authentication = delegate.convert(request);
|
||||
if (authentication != null) {
|
||||
|
@ -66,6 +66,7 @@ public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPo
|
||||
|
||||
private final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints;
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private AuthenticationEntryPoint defaultEntryPoint;
|
||||
|
||||
public DelegatingAuthenticationEntryPoint(LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints) {
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
@ -187,7 +188,8 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
* Builds a URL to redirect the supplied request to HTTPS. Used to redirect the
|
||||
* current request to HTTPS, before doing a forward to the login page.
|
||||
*/
|
||||
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request) throws IOException, ServletException {
|
||||
protected @Nullable String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
|
||||
throws IOException, ServletException {
|
||||
int serverPort = this.portResolver.getServerPort(request);
|
||||
Integer httpsPort = this.portMapper.lookupHttpsPort(serverPort);
|
||||
if (httpsPort != null) {
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@ -32,7 +33,7 @@ import org.springframework.security.core.Authentication;
|
||||
public class NullRememberMeServices implements RememberMeServices {
|
||||
|
||||
@Override
|
||||
public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
|
||||
public @Nullable Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@ -69,7 +70,7 @@ public interface RememberMeServices {
|
||||
* @return a valid authentication object, or <code>null</code> if the request should
|
||||
* not be authenticated
|
||||
*/
|
||||
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
|
||||
@Nullable Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* Called whenever an interactive authentication attempt was made, but the credentials
|
||||
|
@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
@ -50,7 +51,7 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private String defaultFailureUrl;
|
||||
private @Nullable String defaultFailureUrl;
|
||||
|
||||
private boolean forwardToDestination = false;
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.Objects;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A holder of selected HTTP details related to a web authentication request.
|
||||
@ -34,7 +35,7 @@ public class WebAuthenticationDetails implements Serializable {
|
||||
|
||||
private final String remoteAddress;
|
||||
|
||||
private final String sessionId;
|
||||
private final @Nullable String sessionId;
|
||||
|
||||
/**
|
||||
* Records the remote address and will also set the session Id if a session already
|
||||
@ -51,12 +52,12 @@ public class WebAuthenticationDetails implements Serializable {
|
||||
* @param sessionId session id
|
||||
* @since 5.7
|
||||
*/
|
||||
public WebAuthenticationDetails(String remoteAddress, String sessionId) {
|
||||
public WebAuthenticationDetails(String remoteAddress, @Nullable String sessionId) {
|
||||
this.remoteAddress = remoteAddress;
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
private static String extractSessionId(HttpServletRequest request) {
|
||||
private static @Nullable String extractSessionId(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession(false);
|
||||
return (session != null) ? session.getId() : null;
|
||||
}
|
||||
@ -74,7 +75,7 @@ public class WebAuthenticationDetails implements Serializable {
|
||||
* from.
|
||||
* @return the session ID
|
||||
*/
|
||||
public String getSessionId() {
|
||||
public @Nullable String getSessionId() {
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
@ -49,7 +50,8 @@ public final class CompositeLogoutHandler implements LogoutHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) {
|
||||
for (LogoutHandler handler : this.logoutHandlers) {
|
||||
handler.logout(request, response, authentication);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import java.util.function.Function;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
@ -72,7 +73,8 @@ public final class CookieClearingLogoutHandler implements LogoutHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) {
|
||||
this.cookiesToClear.forEach((f) -> response.addCookie(f.apply(request)));
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
@ -39,7 +40,7 @@ public class DelegatingLogoutSuccessHandler implements LogoutSuccessHandler {
|
||||
|
||||
private final LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler;
|
||||
|
||||
private LogoutSuccessHandler defaultLogoutSuccessHandler;
|
||||
private @Nullable LogoutSuccessHandler defaultLogoutSuccessHandler;
|
||||
|
||||
public DelegatingLogoutSuccessHandler(LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler) {
|
||||
Assert.notEmpty(matcherToHandler, "matcherToHandler cannot be null");
|
||||
@ -47,8 +48,8 @@ public class DelegatingLogoutSuccessHandler implements LogoutSuccessHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException, ServletException {
|
||||
for (Map.Entry<RequestMatcher, LogoutSuccessHandler> entry : this.matcherToHandler.entrySet()) {
|
||||
RequestMatcher matcher = entry.getKey();
|
||||
if (matcher.matches(request)) {
|
||||
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
@ -47,8 +48,8 @@ public class ForwardLogoutSuccessHandler implements LogoutSuccessHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException, ServletException {
|
||||
request.getRequestDispatcher(this.targetUrl).forward(request, response);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication.logout;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.header.HeaderWriter;
|
||||
@ -42,7 +43,8 @@ public final class HeaderWriterLogoutHandler implements LogoutHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) {
|
||||
this.headerWriter.writeHeaders(request, response);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -61,8 +62,8 @@ public class HttpStatusReturningLogoutSuccessHandler implements LogoutSuccessHan
|
||||
* . Sets the status on the {@link HttpServletResponse}.
|
||||
*/
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException {
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException {
|
||||
response.setStatus(this.httpStatusToReturn.value());
|
||||
response.getWriter().flush();
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ public class LogoutFilter extends GenericFilterBean {
|
||||
* intended to perform the actual logout functionality (such as clearing the security
|
||||
* context, invalidating the session, etc.).
|
||||
*/
|
||||
@SuppressWarnings("NullAway") // Dataflow analysis limitation
|
||||
public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers) {
|
||||
this.handler = new CompositeLogoutHandler(handlers);
|
||||
Assert.notNull(logoutSuccessHandler, "logoutSuccessHandler cannot be null");
|
||||
@ -76,6 +77,7 @@ public class LogoutFilter extends GenericFilterBean {
|
||||
setFilterProcessesUrl("/logout");
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullAway") // Dataflow analysis limitation
|
||||
public LogoutFilter(String logoutSuccessUrl, LogoutHandler... handlers) {
|
||||
this.handler = new CompositeLogoutHandler(handlers);
|
||||
Assert.isTrue(!StringUtils.hasLength(logoutSuccessUrl) || UrlUtils.isValidRedirectUrl(logoutSuccessUrl),
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication.logout;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@ -37,6 +38,6 @@ public interface LogoutHandler {
|
||||
* @param response the HTTP response
|
||||
* @param authentication the current principal details
|
||||
*/
|
||||
void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication);
|
||||
void logout(HttpServletRequest request, HttpServletResponse response, @Nullable Authentication authentication);
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication.logout;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@ -32,10 +33,11 @@ import org.springframework.security.core.Authentication;
|
||||
*/
|
||||
public final class LogoutSuccessEventPublishingLogoutHandler implements LogoutHandler, ApplicationEventPublisherAware {
|
||||
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
private @Nullable ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) {
|
||||
if (this.eventPublisher == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@ -37,7 +38,7 @@ import org.springframework.security.core.Authentication;
|
||||
*/
|
||||
public interface LogoutSuccessHandler {
|
||||
|
||||
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException;
|
||||
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException, ServletException;
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -64,7 +65,8 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
|
||||
* @param authentication not used (can be <code>null</code>)
|
||||
*/
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) {
|
||||
Assert.notNull(request, "HttpServletRequest required");
|
||||
if (this.invalidateHttpSession) {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler;
|
||||
@ -36,8 +37,8 @@ public class SimpleUrlLogoutSuccessHandler extends AbstractAuthenticationTargetU
|
||||
implements LogoutSuccessHandler {
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException {
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@Nullable Authentication authentication) throws IOException, ServletException {
|
||||
super.handle(request, response, authentication);
|
||||
}
|
||||
|
||||
|
@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Logout functionality based around a filter which handles a specific logout URL.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication.logout;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web.authentication.ott;
|
||||
import java.time.Duration;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.ott.GenerateOneTimeTokenRequest;
|
||||
import org.springframework.util.Assert;
|
||||
@ -38,7 +39,7 @@ public final class DefaultGenerateOneTimeTokenRequestResolver implements Generat
|
||||
private Duration expiresIn = DEFAULT_EXPIRES_IN;
|
||||
|
||||
@Override
|
||||
public GenerateOneTimeTokenRequest resolve(HttpServletRequest request) {
|
||||
public @Nullable GenerateOneTimeTokenRequest resolve(HttpServletRequest request) {
|
||||
String username = request.getParameter("username");
|
||||
if (!StringUtils.hasText(username)) {
|
||||
return null;
|
||||
|
@ -74,11 +74,11 @@ public final class GenerateOneTimeTokenFilter extends OncePerRequestFilter {
|
||||
return;
|
||||
}
|
||||
GenerateOneTimeTokenRequest generateRequest = this.requestResolver.resolve(request);
|
||||
OneTimeToken ott = this.tokenService.generate(generateRequest);
|
||||
if (generateRequest == null) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
OneTimeToken ott = this.tokenService.generate(generateRequest);
|
||||
this.tokenGenerationSuccessHandler.handle(request, response, ott);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.security.web.authentication.ott;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.ott.OneTimeTokenAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -39,7 +40,7 @@ public class OneTimeTokenAuthenticationConverter implements AuthenticationConver
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Override
|
||||
public Authentication convert(HttpServletRequest request) {
|
||||
public @Nullable Authentication convert(HttpServletRequest request) {
|
||||
String token = request.getParameter("token");
|
||||
if (!StringUtils.hasText(token)) {
|
||||
this.logger.debug("No token found in request");
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package for One Time Token usage.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication.ott;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -18,4 +18,7 @@
|
||||
* Authentication processing mechanisms, which respond to the submission of authentication
|
||||
* credentials using various protocols (eg BASIC, CAS, form login etc).
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -25,6 +25,7 @@ import java.util.Locale;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.password.CompromisedPasswordChecker;
|
||||
import org.springframework.security.authentication.password.CompromisedPasswordDecision;
|
||||
@ -60,7 +61,7 @@ public final class HaveIBeenPwnedRestApiPasswordChecker implements CompromisedPa
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompromisedPasswordDecision check(String password) {
|
||||
public CompromisedPasswordDecision check(@Nullable String password) {
|
||||
if (password == null) {
|
||||
return new CompromisedPasswordDecision(false);
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes for Password APIs.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication.password;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -25,6 +25,7 @@ import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@ -96,11 +97,12 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private ApplicationEventPublisher eventPublisher = null;
|
||||
private @Nullable ApplicationEventPublisher eventPublisher = null;
|
||||
|
||||
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||
|
||||
private AuthenticationManager authenticationManager = null;
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
private boolean continueFilterChainOnUnsuccessfulAuthentication = true;
|
||||
|
||||
@ -108,9 +110,9 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||
|
||||
private boolean invalidateSessionOnPrincipalChange = true;
|
||||
|
||||
private AuthenticationSuccessHandler authenticationSuccessHandler = null;
|
||||
private @Nullable AuthenticationSuccessHandler authenticationSuccessHandler = null;
|
||||
|
||||
private AuthenticationFailureHandler authenticationFailureHandler = null;
|
||||
private @Nullable AuthenticationFailureHandler authenticationFailureHandler = null;
|
||||
|
||||
private RequestMatcher requiresAuthenticationRequestMatcher = new PreAuthenticatedProcessingRequestMatcher();
|
||||
|
||||
@ -357,14 +359,14 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||
/**
|
||||
* Override to extract the principal information from the current request
|
||||
*/
|
||||
protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request);
|
||||
protected abstract @Nullable Object getPreAuthenticatedPrincipal(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* Override to extract the credentials (if applicable) from the current request.
|
||||
* Should not return null for a valid principal, though some implementations may
|
||||
* return a dummy value.
|
||||
*/
|
||||
protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request);
|
||||
protected abstract @Nullable Object getPreAuthenticatedCredentials(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* Request matcher for default auth check logic
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -51,6 +52,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PreAuthenticatedAuthenticationProvider.class);
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> preAuthenticatedUserDetailsService;
|
||||
|
||||
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
|
||||
@ -74,7 +76,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
|
||||
* be ignored to allow other providers to authenticate it.
|
||||
*/
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
public @Nullable Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
if (!supports(authentication.getClass())) {
|
||||
return null;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
@ -34,7 +36,7 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
|
||||
|
||||
private final Object principal;
|
||||
|
||||
private final Object credentials;
|
||||
private final @Nullable Object credentials;
|
||||
|
||||
/**
|
||||
* Constructor used for an authentication request. The
|
||||
@ -43,7 +45,7 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
|
||||
* @param aPrincipal The pre-authenticated principal
|
||||
* @param aCredentials The pre-authenticated credentials
|
||||
*/
|
||||
public PreAuthenticatedAuthenticationToken(Object aPrincipal, Object aCredentials) {
|
||||
public PreAuthenticatedAuthenticationToken(Object aPrincipal, @Nullable Object aCredentials) {
|
||||
super(null);
|
||||
this.principal = aPrincipal;
|
||||
this.credentials = aCredentials;
|
||||
@ -56,7 +58,7 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
|
||||
* @param aPrincipal The authenticated principal
|
||||
* @param anAuthorities The granted authorities
|
||||
*/
|
||||
public PreAuthenticatedAuthenticationToken(Object aPrincipal, Object aCredentials,
|
||||
public PreAuthenticatedAuthenticationToken(Object aPrincipal, @Nullable Object aCredentials,
|
||||
Collection<? extends GrantedAuthority> anAuthorities) {
|
||||
super(anAuthorities);
|
||||
this.principal = aPrincipal;
|
||||
@ -68,7 +70,7 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
|
||||
* Get the credentials
|
||||
*/
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
public @Nullable Object getCredentials() {
|
||||
return this.credentials;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@ -46,7 +47,7 @@ public class RequestAttributeAuthenticationFilter extends AbstractPreAuthenticat
|
||||
|
||||
private String principalEnvironmentVariable = "REMOTE_USER";
|
||||
|
||||
private String credentialsEnvironmentVariable;
|
||||
private @Nullable String credentialsEnvironmentVariable;
|
||||
|
||||
private boolean exceptionIfVariableMissing = true;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@ -47,7 +48,7 @@ public class RequestHeaderAuthenticationFilter extends AbstractPreAuthenticatedP
|
||||
|
||||
private String principalRequestHeader = "SM_USER";
|
||||
|
||||
private String credentialsRequestHeader;
|
||||
private @Nullable String credentialsRequestHeader;
|
||||
|
||||
private boolean exceptionIfHeaderMissing = true;
|
||||
|
||||
|
@ -52,6 +52,7 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource implements
|
||||
/**
|
||||
* The role attributes returned by the configured {@code MappableAttributesRetriever}
|
||||
*/
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
protected Set<String> j2eeMappableRoles;
|
||||
|
||||
protected Attributes2GrantedAuthoritiesMapper j2eeUserRoles2GrantedAuthoritiesMapper = new SimpleAttributes2GrantedAuthoritiesMapper();
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.web.authentication.preauth.j2ee;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||
@ -35,7 +36,7 @@ public class J2eePreAuthenticatedProcessingFilter extends AbstractPreAuthenticat
|
||||
* Return the J2EE user name.
|
||||
*/
|
||||
@Override
|
||||
protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpRequest) {
|
||||
protected @Nullable Object getPreAuthenticatedPrincipal(HttpServletRequest httpRequest) {
|
||||
Object principal = (httpRequest.getUserPrincipal() != null) ? httpRequest.getUserPrincipal().getName() : null;
|
||||
this.logger.debug(LogMessage.format("PreAuthenticated J2EE principal: %s", principal));
|
||||
return principal;
|
||||
|
@ -32,6 +32,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
@ -60,9 +61,9 @@ public class WebXmlMappableAttributesRetriever
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
private @Nullable ResourceLoader resourceLoader;
|
||||
|
||||
private Set<String> mappableAttributes;
|
||||
private Set<String> mappableAttributes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
@ -81,6 +82,7 @@ public class WebXmlMappableAttributesRetriever
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.resourceLoader, "resourceLoader cannot be null");
|
||||
Resource webXml = this.resourceLoader.getResource("/WEB-INF/web.xml");
|
||||
Document doc = getDocument(webXml.getInputStream());
|
||||
NodeList webApp = doc.getElementsByTagName("web-app");
|
||||
|
@ -21,4 +21,7 @@
|
||||
* into the security methods exposed by {@code HttpServletRequest} to build
|
||||
* {@code Authentication} object for the user.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication.preauth.j2ee;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -18,4 +18,7 @@
|
||||
* Support for "pre-authenticated" scenarios, where Spring Security assumes the incoming
|
||||
* request has already been authenticated by some externally configured system.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
@ -30,6 +30,7 @@ import javax.security.auth.Subject;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
|
||||
@ -50,16 +51,16 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
|
||||
private static final String USER_REGISTRY = "UserRegistry";
|
||||
|
||||
private static Method getRunAsSubject = null;
|
||||
private static @Nullable Method getRunAsSubject = null;
|
||||
|
||||
private static Method getGroupsForUser = null;
|
||||
private static @Nullable Method getGroupsForUser = null;
|
||||
|
||||
private static Method getSecurityName = null;
|
||||
private static @Nullable Method getSecurityName = null;
|
||||
|
||||
private static Method narrow = null;
|
||||
private static @Nullable Method narrow = null;
|
||||
|
||||
// SEC-803
|
||||
private static Class<?> wsCredentialClass = null;
|
||||
private static @Nullable Class<?> wsCredentialClass = null;
|
||||
|
||||
@Override
|
||||
public List<String> getGroupsForCurrentUser() {
|
||||
@ -67,7 +68,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentUserName() {
|
||||
public @Nullable String getCurrentUserName() {
|
||||
return getSecurityName(getRunAsSubject());
|
||||
}
|
||||
|
||||
@ -76,7 +77,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
* @param subject The subject for which to retrieve the security name
|
||||
* @return String the security name for the given subject
|
||||
*/
|
||||
private static String getSecurityName(final Subject subject) {
|
||||
private static @Nullable String getSecurityName(final Subject subject) {
|
||||
logger.debug(LogMessage.format("Determining Websphere security name for subject %s", subject));
|
||||
String userSecurityName = null;
|
||||
if (subject != null) {
|
||||
@ -116,7 +117,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
* @return the WebSphere group names for the given security name
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<String> getWebSphereGroups(final String securityName) {
|
||||
private static List<String> getWebSphereGroups(final @Nullable String securityName) {
|
||||
Context context = null;
|
||||
try {
|
||||
// TODO: Cache UserRegistry object
|
||||
@ -140,7 +141,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
}
|
||||
}
|
||||
|
||||
private static void closeContext(Context context) {
|
||||
private static void closeContext(@Nullable Context context) {
|
||||
try {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
@ -151,7 +152,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
|
||||
}
|
||||
}
|
||||
|
||||
private static Object invokeMethod(Method method, Object instance, Object... args) {
|
||||
private static Object invokeMethod(Method method, @Nullable Object instance, Object... args) {
|
||||
try {
|
||||
return method.invoke(instance, args);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.web.authentication.preauth.websphere;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Provides indirection between classes using websphere and the actual container
|
||||
* interaction, allowing for easier unit testing.
|
||||
@ -31,6 +33,6 @@ interface WASUsernameAndGroupsExtractor {
|
||||
|
||||
List<String> getGroupsForCurrentUser();
|
||||
|
||||
String getCurrentUserName();
|
||||
@Nullable String getCurrentUserName();
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user