mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-10-22 10:18:53 +00:00
Enable Null checking in spring-security-web via JSpecify
Closes gh-16882
This commit is contained in:
parent
a58f3282d9
commit
be64c67af5
@ -1,3 +1,7 @@
|
||||
plugins {
|
||||
id 'security-nullability'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.spring-module'
|
||||
|
||||
dependencies {
|
||||
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
@ -49,12 +50,16 @@ public class DefaultMessageSecurityExpressionHandler<T> extends AbstractSecurity
|
||||
Message<T> message) {
|
||||
MessageSecurityExpressionRoot root = createSecurityExpressionRoot(authentication, message);
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(root);
|
||||
ctx.setBeanResolver(getBeanResolver());
|
||||
BeanResolver beanResolver = getBeanResolver();
|
||||
if (beanResolver != null) {
|
||||
// https://github.com/spring-projects/spring-framework/issues/35371
|
||||
ctx.setBeanResolver(beanResolver);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication,
|
||||
Message<T> invocation) {
|
||||
return createSecurityExpressionRoot(() -> authentication, invocation);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public final class MessageAuthorizationContextSecurityExpressionHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public EvaluationContext createEvaluationContext(Authentication authentication,
|
||||
public EvaluationContext createEvaluationContext(@Nullable Authentication authentication,
|
||||
MessageAuthorizationContext<?> message) {
|
||||
return createEvaluationContext(() -> authentication, message);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.access.expression;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.messaging.Message;
|
||||
@ -60,7 +62,7 @@ class MessageExpressionConfigAttribute implements ConfigAttribute, EvaluationCon
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute() {
|
||||
public @Nullable String getAttribute() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.access.expression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
@ -60,7 +62,7 @@ public class MessageExpressionVoter<T> implements AccessDecisionVoter<Message<T>
|
||||
return ExpressionUtils.evaluateAsBoolean(attr.getAuthorizeExpression(), ctx) ? ACCESS_GRANTED : ACCESS_DENIED;
|
||||
}
|
||||
|
||||
private MessageExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
|
||||
private @Nullable MessageExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
|
||||
for (ConfigAttribute attribute : attributes) {
|
||||
if (attribute instanceof MessageExpressionConfigAttribute) {
|
||||
return (MessageExpressionConfigAttribute) attribute;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Security expression support for {@link org.springframework.messaging.Message}.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.access.expression;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.messaging.Message;
|
||||
@ -110,7 +111,7 @@ public final class AuthorizationChannelInterceptor implements ChannelInterceptor
|
||||
|
||||
@Override
|
||||
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||
AuthorizationResult result) {
|
||||
@Nullable AuthorizationResult result) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.security.messaging.access.intercept;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
@ -83,7 +85,7 @@ public final class ChannelSecurityInterceptor extends AbstractSecurityIntercepto
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) {
|
||||
public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, @Nullable Exception ex) {
|
||||
InterceptorStatusToken token = clearToken();
|
||||
finallyInvocation(token);
|
||||
}
|
||||
@ -99,7 +101,7 @@ public final class ChannelSecurityInterceptor extends AbstractSecurityIntercepto
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterReceiveCompletion(Message<?> message, MessageChannel channel, Exception ex) {
|
||||
public void afterReceiveCompletion(@Nullable Message<?> message, MessageChannel channel, @Nullable Exception ex) {
|
||||
}
|
||||
|
||||
private InterceptorStatusToken clearToken() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.security.messaging.access.intercept;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -61,7 +62,7 @@ public final class DefaultMessageSecurityMetadataSource implements MessageSecuri
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +55,7 @@ public final class MessageMatcherDelegatingAuthorizationManager implements Autho
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
|
||||
public @Nullable AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
|
||||
Message<?> message) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace(LogMessage.format("Authorizing message"));
|
||||
@ -75,7 +75,8 @@ public final class MessageMatcherDelegatingAuthorizationManager implements Autho
|
||||
return null;
|
||||
}
|
||||
|
||||
private MessageAuthorizationContext<?> authorizationContext(MessageMatcher<?> matcher, Message<?> message) {
|
||||
private @Nullable MessageAuthorizationContext<?> authorizationContext(MessageMatcher<?> matcher,
|
||||
Message<?> message) {
|
||||
MessageMatcher.MatchResult matchResult = matcher.matcher((Message) message);
|
||||
if (!matchResult.isMatch()) {
|
||||
return null;
|
||||
@ -179,7 +180,7 @@ public final class MessageMatcherDelegatingAuthorizationManager implements Autho
|
||||
* @return the {@link Builder.Constraint} that is associated to the
|
||||
* {@link MessageMatcher}
|
||||
*/
|
||||
private Builder.Constraint simpDestMatchers(SimpMessageType type, String... patterns) {
|
||||
private Builder.Constraint simpDestMatchers(@Nullable SimpMessageType type, String... patterns) {
|
||||
List<MessageMatcher<?>> matchers = new ArrayList<>(patterns.length);
|
||||
for (String pattern : patterns) {
|
||||
MessageMatcher<Object> matcher = this.messageMatcherBuilder.matcher(type, pattern);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Authorization support for {@link org.springframework.messaging.Message}.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.access.intercept;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.context;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
@ -110,13 +112,14 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, Message<?> message) {
|
||||
public @Nullable Object resolveArgument(MethodParameter parameter, Message<?> message) {
|
||||
Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
|
||||
if (authentication == null) {
|
||||
return null;
|
||||
}
|
||||
Object principal = authentication.getPrincipal();
|
||||
AuthenticationPrincipal authPrincipal = findMethodAnnotation(parameter);
|
||||
Assert.notNull(authPrincipal, "AuthenticationPrincipal must not be null. Run supports first");
|
||||
String expressionToParse = authPrincipal.expression();
|
||||
if (StringUtils.hasLength(expressionToParse)) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
@ -165,7 +168,7 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
|
||||
* @param parameter the {@link MethodParameter} to search for an {@link Annotation}
|
||||
* @return the {@link Annotation} that was found or null.
|
||||
*/
|
||||
private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) {
|
||||
private @Nullable AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) {
|
||||
if (this.useAnnotationTemplate) {
|
||||
return this.scanner.scan(parameter.getParameter());
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.context;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
@ -96,7 +98,7 @@ public final class SecurityContextChannelInterceptor implements ExecutorChannelI
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) {
|
||||
public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, @Nullable Exception ex) {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@ -107,7 +109,8 @@ public final class SecurityContextChannelInterceptor implements ExecutorChannelI
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler, Exception ex) {
|
||||
public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler,
|
||||
@Nullable Exception ex) {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@ -131,7 +134,7 @@ public final class SecurityContextChannelInterceptor implements ExecutorChannelI
|
||||
this.securityContextHolderStrategy.setContext(context);
|
||||
}
|
||||
|
||||
private Authentication getAuthentication(Object user) {
|
||||
private Authentication getAuthentication(@Nullable Object user) {
|
||||
if ((user instanceof Authentication)) {
|
||||
return (Authentication) user;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.context;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
@ -121,7 +123,8 @@ public final class SecurityContextPropagationChannelInterceptor implements Execu
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler, Exception ex) {
|
||||
public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler,
|
||||
@Nullable Exception ex) {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support for establishing the
|
||||
* {@link org.springframework.security.core.context.SecurityContext} within messaging.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.context;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.handler.invocation.reactive;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@ -108,7 +110,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg
|
||||
|
||||
private boolean useAnnotationTemplate = false;
|
||||
|
||||
private BeanResolver beanResolver;
|
||||
private @Nullable BeanResolver beanResolver;
|
||||
|
||||
private ReactiveAdapterRegistry adapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
|
||||
|
||||
@ -149,7 +151,8 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
private Object resolvePrincipal(MethodParameter parameter, Object principal) {
|
||||
@NullUnmarked
|
||||
private @Nullable Object resolvePrincipal(MethodParameter parameter, @Nullable Object principal) {
|
||||
AuthenticationPrincipal authPrincipal = findMethodAnnotation(parameter);
|
||||
String expressionToParse = authPrincipal.expression();
|
||||
if (StringUtils.hasLength(expressionToParse)) {
|
||||
@ -169,7 +172,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg
|
||||
return principal;
|
||||
}
|
||||
|
||||
private boolean isInvalidType(MethodParameter parameter, Object principal) {
|
||||
private boolean isInvalidType(MethodParameter parameter, @Nullable Object principal) {
|
||||
if (principal == null) {
|
||||
return false;
|
||||
}
|
||||
@ -206,7 +209,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg
|
||||
* @param parameter the {@link MethodParameter} to search for an {@link Annotation}
|
||||
* @return the {@link Annotation} that was found or null.
|
||||
*/
|
||||
private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) {
|
||||
private @Nullable AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) {
|
||||
if (this.useAnnotationTemplate) {
|
||||
return this.scanner.scan(parameter.getParameter());
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.security.messaging.handler.invocation.reactive;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@ -106,7 +107,7 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu
|
||||
|
||||
private boolean useAnnotationTemplate = false;
|
||||
|
||||
private BeanResolver beanResolver;
|
||||
private @Nullable BeanResolver beanResolver;
|
||||
|
||||
private ReactiveAdapterRegistry adapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
|
||||
|
||||
@ -159,7 +160,7 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
private Object resolveSecurityContext(MethodParameter parameter, Object securityContext) {
|
||||
private @Nullable Object resolveSecurityContext(MethodParameter parameter, Object securityContext) {
|
||||
CurrentSecurityContext contextAnno = findMethodAnnotation(parameter);
|
||||
if (contextAnno != null) {
|
||||
return resolveSecurityContextFromAnnotation(contextAnno, parameter, securityContext);
|
||||
@ -167,14 +168,17 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu
|
||||
return securityContext;
|
||||
}
|
||||
|
||||
private Object resolveSecurityContextFromAnnotation(CurrentSecurityContext contextAnno, MethodParameter parameter,
|
||||
Object securityContext) {
|
||||
private @Nullable Object resolveSecurityContextFromAnnotation(CurrentSecurityContext contextAnno,
|
||||
MethodParameter parameter, Object securityContext) {
|
||||
String expressionToParse = contextAnno.expression();
|
||||
if (StringUtils.hasLength(expressionToParse)) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setRootObject(securityContext);
|
||||
context.setVariable("this", securityContext);
|
||||
context.setBeanResolver(this.beanResolver);
|
||||
if (this.beanResolver != null) {
|
||||
// https://github.com/spring-projects/spring-framework/issues/35371
|
||||
context.setBeanResolver(this.beanResolver);
|
||||
}
|
||||
Expression expression = this.parser.parseExpression(expressionToParse);
|
||||
securityContext = expression.getValue(context);
|
||||
}
|
||||
@ -187,7 +191,7 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu
|
||||
return securityContext;
|
||||
}
|
||||
|
||||
private boolean isInvalidType(MethodParameter parameter, Object value) {
|
||||
private boolean isInvalidType(MethodParameter parameter, @Nullable Object value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
@ -223,7 +227,7 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu
|
||||
* @param parameter the {@link MethodParameter} to search for an {@link Annotation}
|
||||
* @return the {@link Annotation} that was found or null.
|
||||
*/
|
||||
private CurrentSecurityContext findMethodAnnotation(MethodParameter parameter) {
|
||||
private @Nullable CurrentSecurityContext findMethodAnnotation(MethodParameter parameter) {
|
||||
if (this.useAnnotationTemplate) {
|
||||
return this.scanner.scan(parameter.getParameter());
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reactive support for resolving security related arguments.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.handler.invocation.reactive;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -107,7 +107,7 @@ public final class PathPatternMessageMatcher implements MessageMatcher<Object> {
|
||||
return (pathMatchInfo != null) ? MatchResult.match(pathMatchInfo.getUriVariables()) : MatchResult.notMatch();
|
||||
}
|
||||
|
||||
private static String getDestination(Message<?> message) {
|
||||
private static @Nullable String getDestination(Message<?> message) {
|
||||
return SimpMessageHeaderAccessor.getDestination(message.getHeaders());
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support for matching messages.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.util.matcher;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -19,6 +19,8 @@ package org.springframework.security.messaging.web.csrf;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
@ -70,7 +72,7 @@ public final class XorCsrfChannelInterceptor implements ChannelInterceptor {
|
||||
* @param actual
|
||||
* @return
|
||||
*/
|
||||
private static boolean equalsConstantTime(String expected, String actual) {
|
||||
private static boolean equalsConstantTime(String expected, @Nullable String actual) {
|
||||
if (expected == actual) {
|
||||
return true;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ package org.springframework.security.messaging.web.csrf;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.security.crypto.codec.Utf8;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@ -33,7 +35,7 @@ final class XorCsrfTokenUtils {
|
||||
private XorCsrfTokenUtils() {
|
||||
}
|
||||
|
||||
static String getTokenValue(String actualToken, String token) {
|
||||
static @Nullable String getTokenValue(@Nullable String actualToken, String token) {
|
||||
byte[] actualBytes;
|
||||
try {
|
||||
actualBytes = Base64.getUrlDecoder().decode(actualToken);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support CSRF protection in messages.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.web.csrf;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -19,6 +19,7 @@ package org.springframework.security.messaging.web.socket.server;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
@ -62,7 +63,7 @@ public final class CsrfTokenHandshakeInterceptor implements HandshakeInterceptor
|
||||
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||
Exception exception) {
|
||||
@Nullable Exception exception) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reactive Security CSRF protection.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.messaging.web.socket.server;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
@ -74,7 +74,7 @@ public class ExpressionBasedMessageSecurityMetadataSourceFactoryTests {
|
||||
@Test
|
||||
public void createExpressionMessageMetadataSourceNoMatch() {
|
||||
Collection<ConfigAttribute> attrs = this.source.getAttributes(this.message);
|
||||
assertThat(attrs).isNull();
|
||||
assertThat(attrs).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,8 +67,8 @@ public class DefaultMessageSecurityMetadataSourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAttributesNull() {
|
||||
assertThat(this.source.getAttributes(this.message)).isNull();
|
||||
public void getAttributesEmpty() {
|
||||
assertThat(this.source.getAttributes(this.message)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user