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