Review nullability of spring-ws-security

See gh-1562
This commit is contained in:
Stéphane Nicoll
2025-05-16 14:40:24 +02:00
parent 16dd68afa6
commit 69673bc962
29 changed files with 140 additions and 68 deletions

View File

@@ -18,11 +18,13 @@ package org.springframework.ws.soap.security;
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
import javax.xml.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.ws.client.WebServiceClientException;
@@ -69,7 +71,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
private boolean skipValidationIfNoHeaderPresent = false;
private EndpointExceptionResolver exceptionResolver;
private @Nullable EndpointExceptionResolver exceptionResolver;
/**
* Indicates whether server-side incoming request are to be validated. Defaults to
@@ -197,7 +199,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
}
@Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
public void afterCompletion(MessageContext messageContext, Object endpoint, @Nullable Exception ex) {
cleanUp();
}
@@ -279,7 +281,8 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
}
@Override
public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {
public void afterCompletion(MessageContext messageContext, @Nullable Exception ex)
throws WebServiceClientException {
cleanUp();
}
@@ -320,7 +323,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
this.logger.debug("No exception resolver present, creating basic soap fault");
}
SoapBody response = ((SoapMessage) messageContext.getResponse()).getSoapBody();
response.addClientOrSenderFault(ex.getMessage(), Locale.ENGLISH);
response.addClientOrSenderFault(Objects.requireNonNull(ex.getMessage()), Locale.ENGLISH);
}
return false;
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap.security;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.WebServiceException;
/**
@@ -32,7 +34,7 @@ public abstract class WsSecurityException extends WebServiceException {
super(msg);
}
public WsSecurityException(String msg, Throwable ex) {
public WsSecurityException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap.security;
import org.jspecify.annotations.Nullable;
/**
* Exception indicating that something went wrong during the securement of a message.
* <p>
@@ -33,7 +35,7 @@ public abstract class WsSecuritySecurementException extends WsSecurityException
super(msg);
}
public WsSecuritySecurementException(String msg, Throwable ex) {
public WsSecuritySecurementException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap.security;
import org.jspecify.annotations.Nullable;
/**
* Exception indicating that something went wrong during the validation of a message.
* <p>
@@ -33,7 +35,7 @@ public abstract class WsSecurityValidationException extends WsSecurityException
super(msg);
}
public WsSecurityValidationException(String msg, Throwable ex) {
public WsSecurityValidationException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -17,4 +17,7 @@
/**
* Contains generic {@code CallbackHandler} implementations.
*/
@NullMarked
package org.springframework.ws.soap.security.callback;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Provides WS-Security implementation classes. Contains the
* {@code AbstractWsSecurityInterceptor} and exceptions.
*/
@NullMarked
package org.springframework.ws.soap.security;
import org.jspecify.annotations.NullMarked;

View File

@@ -21,6 +21,8 @@ import java.security.KeyStore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;
@@ -38,21 +40,21 @@ import org.springframework.util.StringUtils;
*/
public class KeyManagersFactoryBean implements FactoryBean<KeyManager[]>, InitializingBean {
private KeyManager[] keyManagers;
private KeyManager @Nullable [] keyManagers;
private KeyStore keyStore;
private @Nullable KeyStore keyStore;
private String algorithm;
private @Nullable String algorithm;
private String provider;
private @Nullable String provider;
private char[] password;
private char @Nullable [] password;
/**
* Sets the password to use for integrity checking. If this property is not set, then
* integrity checking is not performed.
*/
public void setPassword(String password) {
public void setPassword(@Nullable String password) {
if (password != null) {
this.password = password.toCharArray();
}
@@ -84,7 +86,7 @@ public class KeyManagersFactoryBean implements FactoryBean<KeyManager[]>, Initia
}
@Override
public KeyManager[] getObject() throws Exception {
public KeyManager @Nullable [] getObject() throws Exception {
return this.keyManagers;
}

View File

@@ -23,10 +23,12 @@ import java.security.KeyStore;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -45,22 +47,22 @@ public class KeyStoreFactoryBean implements FactoryBean<KeyStore>, InitializingB
private static final Log logger = LogFactory.getLog(KeyStoreFactoryBean.class);
private KeyStore keyStore;
private @Nullable KeyStore keyStore;
private String type;
private @Nullable String type;
private String provider;
private @Nullable String provider;
private Resource location;
private @Nullable Resource location;
private char[] password;
private char @Nullable [] password;
/**
* Sets the location of the key store to use. If this is not set, a new, empty key
* store will be used.
* @see KeyStore#load(java.io.InputStream,char[])
*/
public void setLocation(Resource location) {
public void setLocation(@Nullable Resource location) {
this.location = location;
}
@@ -68,7 +70,7 @@ public class KeyStoreFactoryBean implements FactoryBean<KeyStore>, InitializingB
* Sets the password to use for integrity checking. If this property is not set, then
* integrity checking is not performed.
*/
public void setPassword(String password) {
public void setPassword(@Nullable String password) {
if (password != null) {
this.password = password.toCharArray();
}
@@ -86,12 +88,13 @@ public class KeyStoreFactoryBean implements FactoryBean<KeyStore>, InitializingB
* used.
* @see KeyStore#getDefaultType()
*/
public void setType(String type) {
public void setType(@Nullable String type) {
this.type = type;
}
@Override
public KeyStore getObject() {
Assert.state(this.keyStore != null, "KeyStore has not been initialized");
return this.keyStore;
}

View File

@@ -21,6 +21,8 @@ import java.security.KeyStore;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;
@@ -37,13 +39,13 @@ import org.springframework.util.StringUtils;
*/
public class TrustManagersFactoryBean implements FactoryBean<TrustManager[]>, InitializingBean {
private TrustManager[] trustManagers;
private TrustManager @Nullable [] trustManagers;
private KeyStore keyStore;
private @Nullable KeyStore keyStore;
private String algorithm;
private @Nullable String algorithm;
private String provider;
private @Nullable String provider;
/**
* Sets the provider of the trust manager to use. If this is not set, the default is
@@ -71,7 +73,7 @@ public class TrustManagersFactoryBean implements FactoryBean<TrustManager[]>, In
}
@Override
public TrustManager[] getObject() throws Exception {
public TrustManager @Nullable [] getObject() throws Exception {
return this.trustManagers;
}

View File

@@ -17,4 +17,7 @@
/**
* Contains support classes for handling WS-Security messages.
*/
@NullMarked
package org.springframework.ws.soap.security.support;
import org.jspecify.annotations.NullMarked;

View File

@@ -26,6 +26,7 @@ import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.HandlerAction;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.handler.WSHandler;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.springframework.util.StringUtils;
@@ -45,11 +46,11 @@ class Wss4jHandler extends WSHandler {
/** Keys are constants from {@link ConfigurationConstants}; values are strings. */
private final Properties options = new Properties();
private String securementPassword;
private @Nullable String securementPassword;
private Crypto securementEncryptionCrypto;
private @Nullable Crypto securementEncryptionCrypto;
private Crypto securementSignatureCrypto;
private @Nullable Crypto securementSignatureCrypto;
Wss4jHandler() {
// set up default handler properties
@@ -94,7 +95,7 @@ class Wss4jHandler extends WSHandler {
}
@Override
public String getPassword(Object msgContext) {
public @Nullable String getPassword(Object msgContext) {
String contextPassword = (String) getProperty(msgContext,
Wss4jSecurityInterceptor.SECUREMENT_PASSWORD_PROPERTY_NAME);
if (StringUtils.hasLength(contextPassword)) {
@@ -104,17 +105,17 @@ class Wss4jHandler extends WSHandler {
}
@Override
public Object getProperty(Object msgContext, String key) {
public @Nullable Object getProperty(Object msgContext, String key) {
return ((MessageContext) msgContext).getProperty(key);
}
@Override
protected Crypto loadEncryptionCrypto(RequestData reqData) throws WSSecurityException {
protected @Nullable Crypto loadEncryptionCrypto(RequestData reqData) throws WSSecurityException {
return this.securementEncryptionCrypto;
}
@Override
public Crypto loadSignatureCrypto(RequestData reqData) throws WSSecurityException {
public @Nullable Crypto loadSignatureCrypto(RequestData reqData) throws WSSecurityException {
return this.securementSignatureCrypto;
}

View File

@@ -22,6 +22,7 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.security.auth.callback.Callback;
@@ -46,6 +47,7 @@ import org.apache.wss4j.dom.validate.Credential;
import org.apache.wss4j.dom.validate.SignatureTrustValidator;
import org.apache.wss4j.dom.validate.TimestampValidator;
import org.apache.wss4j.dom.validate.Validator;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -54,6 +56,7 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.security.AbstractWsSecurityInterceptor;
import org.springframework.ws.soap.security.WsSecuritySecurementException;
@@ -160,21 +163,21 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
*/
public static final String SECUREMENT_PASSWORD_PROPERTY_NAME = "Wss4jSecurityInterceptor.securementPassword";
private String securementActions;
private @Nullable String securementActions;
private String securementUsername;
private @Nullable String securementUsername;
private CallbackHandler validationCallbackHandler;
private @Nullable CallbackHandler validationCallbackHandler;
private String validationActions;
private @Nullable String validationActions;
private List<Integer> validationActionsVector;
private List<Integer> validationActionsVector = Collections.emptyList();
private String validationActor;
private @Nullable String validationActor;
private Crypto validationDecryptionCrypto;
private @Nullable Crypto validationDecryptionCrypto;
private Crypto validationSignatureCrypto;
private @Nullable Crypto validationSignatureCrypto;
private boolean timestampStrict = true;
@@ -186,7 +189,7 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
private int futureTimeToLive = 60;
private WSSConfig wssConfig;
private @Nullable WSSConfig wssConfig;
private final Wss4jHandler handler = new Wss4jHandler();
@@ -200,9 +203,9 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
private boolean securementUseDerivedKey;
private CallbackHandler samlCallbackHandler;
private @Nullable CallbackHandler samlCallbackHandler;
private CallbackHandler attachmentCallbackHandler;
private @Nullable CallbackHandler attachmentCallbackHandler;
// Allow RSA 15 to maintain default behavior
private boolean allowRSA15KeyTransportAlgorithm = true;
@@ -871,7 +874,10 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
soapMessage.setDocument(envelopeAsDocument);
if (this.getRemoveSecurityHeader()) {
soapMessage.getEnvelope().getHeader().removeHeaderElement(WS_SECURITY_NAME);
SoapHeader header = soapMessage.getEnvelope().getHeader();
if (header != null) {
header.removeHeaderElement(WS_SECURITY_NAME);
}
}
}
@@ -973,7 +979,7 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
if (principal instanceof WSUsernameTokenPrincipalImpl usernameTokenPrincipal) {
UsernameTokenPrincipalCallback callback = new UsernameTokenPrincipalCallback(usernameTokenPrincipal);
try {
this.validationCallbackHandler.handle(new Callback[] { callback });
Objects.requireNonNull(this.validationCallbackHandler).handle(new Callback[] { callback });
}
catch (IOException ex) {
this.logger.warn("Principal callback resulted in IOException", ex);

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap.security.wss4j2;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.soap.security.WsSecuritySecurementException;
/**
@@ -33,7 +35,7 @@ public class Wss4jSecuritySecurementException extends WsSecuritySecurementExcept
super(msg);
}
public Wss4jSecuritySecurementException(String msg, Throwable ex) {
public Wss4jSecuritySecurementException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.ws.soap.security.wss4j2;
import org.jspecify.annotations.Nullable;
import org.springframework.ws.soap.security.WsSecurityValidationException;
/**
@@ -33,7 +35,7 @@ public class Wss4jSecurityValidationException extends WsSecurityValidationExcept
super(msg);
}
public Wss4jSecurityValidationException(String msg, Throwable ex) {
public Wss4jSecurityValidationException(@Nullable String msg, Throwable ex) {
super(msg, ex);
}

View File

@@ -22,10 +22,12 @@ import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.Objects;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ws.soap.security.support.KeyStoreUtils;
@@ -43,10 +45,11 @@ import org.springframework.ws.soap.security.support.KeyStoreUtils;
*/
public class KeyStoreCallbackHandler extends AbstractWsPasswordCallbackHandler implements InitializingBean {
private String privateKeyPassword;
private @Nullable String privateKeyPassword;
private char[] symmetricKeyPassword;
private char @Nullable [] symmetricKeyPassword;
@SuppressWarnings("NullAway.Init")
private KeyStore keyStore;
/**
@@ -75,7 +78,7 @@ public class KeyStoreCallbackHandler extends AbstractWsPasswordCallbackHandler i
try {
key = this.keyStore.getKey(id, (this.symmetricKeyPassword != null) ? this.symmetricKeyPassword
: this.privateKeyPassword.toCharArray());
: Objects.requireNonNull(this.privateKeyPassword).toCharArray());
}
catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException ex) {
throw new IOException("Could not get key", ex);
@@ -93,7 +96,7 @@ public class KeyStoreCallbackHandler extends AbstractWsPasswordCallbackHandler i
* Sets the password used to retrieve private keys from the keystore. This property is
* required for decryption based on private keys, and signing.
*/
public void setPrivateKeyPassword(String privateKeyPassword) {
public void setPrivateKeyPassword(@Nullable String privateKeyPassword) {
if (privateKeyPassword != null) {
this.privateKeyPassword = privateKeyPassword;
}
@@ -104,7 +107,7 @@ public class KeyStoreCallbackHandler extends AbstractWsPasswordCallbackHandler i
* property is not set, it defaults to the private key password.
* @see #setPrivateKeyPassword(String)
*/
public void setSymmetricKeyPassword(String symmetricKeyPassword) {
public void setSymmetricKeyPassword(@Nullable String symmetricKeyPassword) {
if (symmetricKeyPassword != null) {
this.symmetricKeyPassword = symmetricKeyPassword.toCharArray();
}
@@ -116,7 +119,7 @@ public class KeyStoreCallbackHandler extends AbstractWsPasswordCallbackHandler i
loadDefaultKeyStore();
}
if (this.symmetricKeyPassword == null) {
this.symmetricKeyPassword = this.privateKeyPassword.toCharArray();
this.symmetricKeyPassword = Objects.requireNonNull(this.privateKeyPassword).toCharArray();
}
}

View File

@@ -17,11 +17,13 @@
package org.springframework.ws.soap.security.wss4j2.callback;
import java.io.IOException;
import java.util.Objects;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
@@ -53,7 +55,7 @@ public class SpringSecurityPasswordValidationCallbackHandler extends AbstractWsP
private UserCache userCache = new NullUserCache();
private UserDetailsService userDetailsService;
private @Nullable UserDetailsService userDetailsService;
/** Sets the users cache. Not required, but can benefit performance. */
public void setUserCache(UserCache userCache) {
@@ -92,7 +94,7 @@ public class SpringSecurityPasswordValidationCallbackHandler extends AbstractWsP
UserDetails user = loadUserDetails(callback.getPrincipal().getName());
WSUsernameTokenPrincipalImpl principal = callback.getPrincipal();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(principal,
principal.getPassword(), user.getAuthorities());
principal.getPassword(), (user != null) ? user.getAuthorities() : null);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Authentication success: " + authRequest);
}
@@ -105,12 +107,12 @@ public class SpringSecurityPasswordValidationCallbackHandler extends AbstractWsP
SecurityContextHolder.clearContext();
}
private UserDetails loadUserDetails(String username) throws DataAccessException {
private @Nullable UserDetails loadUserDetails(String username) throws DataAccessException {
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
try {
user = this.userDetailsService.loadUserByUsername(username);
user = Objects.requireNonNull(this.userDetailsService).loadUserByUsername(username);
}
catch (UsernameNotFoundException notFound) {
if (this.logger.isDebugEnabled()) {

View File

@@ -17,4 +17,7 @@
/**
* Contains {@code CallbackHandler} implementations for WSS4J 2.0+.
*/
@NullMarked
package org.springframework.ws.soap.security.wss4j2.callback;
import org.jspecify.annotations.NullMarked;

View File

@@ -18,4 +18,7 @@
* Contains classes for using the <a href="http://ws.apache.org/wss4j/">Apache WSS4J
* 2.0+</a> WS-Security implementation within Spring-WS.
*/
@NullMarked
package org.springframework.ws.soap.security.wss4j2;
import org.jspecify.annotations.NullMarked;

View File

@@ -22,6 +22,7 @@ import java.util.Properties;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import org.apache.wss4j.common.crypto.Merlin;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
@@ -46,7 +47,7 @@ public class CryptoFactoryBean implements FactoryBean<Crypto>, InitializingBean
private final Properties configuration = new Properties();
private Crypto crypto;
private @Nullable Crypto crypto;
private static final String CRYPTO_PROVIDER_PROPERTY = "org.apache.wss4j.crypto.provider";
@@ -179,7 +180,7 @@ public class CryptoFactoryBean implements FactoryBean<Crypto>, InitializingBean
}
@Override
public Crypto getObject() throws Exception {
public @Nullable Crypto getObject() throws Exception {
return this.crypto;
}

View File

@@ -17,4 +17,7 @@
/**
* Contains support classes for working with WSS4J 2.0+.
*/
@NullMarked
package org.springframework.ws.soap.security.wss4j2.support;
import org.jspecify.annotations.NullMarked;

View File

@@ -20,6 +20,7 @@ import java.security.cert.X509Certificate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
@@ -56,6 +57,7 @@ public class X509AuthenticationProvider implements AuthenticationProvider, Initi
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@SuppressWarnings("NullAway.Init")
private X509AuthoritiesPopulator x509AuthoritiesPopulator;
private X509UserCache userCache = new NullX509UserCache();
@@ -88,7 +90,7 @@ public class X509AuthenticationProvider implements AuthenticationProvider, Initi
* authentication request.
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
public @Nullable Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
return null;
}

View File

@@ -20,6 +20,8 @@ import java.io.Serial;
import java.security.cert.X509Certificate;
import java.util.Collection;
import org.jspecify.annotations.Nullable;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
@@ -39,7 +41,7 @@ public class X509AuthenticationToken extends AbstractAuthenticationToken {
@Serial
private static final long serialVersionUID = 1L;
private Object principal;
private @Nullable Object principal;
private final X509Certificate credentials;
@@ -82,7 +84,7 @@ public class X509AuthenticationToken extends AbstractAuthenticationToken {
}
@Override
public Object getPrincipal() {
public @Nullable Object getPrincipal() {
return this.principal;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.soap.security.x509.cache;
import java.security.cert.X509Certificate;
import org.jspecify.annotations.Nullable;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -34,7 +36,7 @@ public class NullX509UserCache implements X509UserCache {
// ========================================================================================================
@Override
public UserDetails getUserFromCache(X509Certificate certificate) {
public @Nullable UserDetails getUserFromCache(X509Certificate certificate) {
return null;
}

View File

@@ -20,6 +20,7 @@ import java.security.cert.X509Certificate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
@@ -40,6 +41,7 @@ public class SpringBasedX509UserCache implements X509UserCache, InitializingBean
private static final Log logger = LogFactory.getLog(SpringBasedX509UserCache.class);
@SuppressWarnings("NullAway.Init")
private Cache cache;
@Override
@@ -48,13 +50,13 @@ public class SpringBasedX509UserCache implements X509UserCache, InitializingBean
}
@Override
public UserDetails getUserFromCache(X509Certificate userCert) {
public @Nullable UserDetails getUserFromCache(X509Certificate userCert) {
if (logger.isDebugEnabled()) {
String subjectDN = "unknown";
if ((userCert != null) && (userCert.getSubjectX500Principal() != null)) {
if (userCert.getSubjectX500Principal() != null) {
subjectDN = userCert.getSubjectX500Principal().toString();
}

View File

@@ -18,6 +18,8 @@ package org.springframework.ws.soap.security.x509.cache;
import java.security.cert.X509Certificate;
import org.jspecify.annotations.Nullable;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -39,7 +41,7 @@ public interface X509UserCache {
// ~ Methods
// ========================================================================================================
UserDetails getUserFromCache(X509Certificate userCertificate);
@Nullable UserDetails getUserFromCache(X509Certificate userCertificate);
void putUserInCache(X509Certificate key, UserDetails user);

View File

@@ -17,4 +17,7 @@
/**
* Caching support for X.509 client certificates.
*/
@NullMarked
package org.springframework.ws.soap.security.x509.cache;
import org.jspecify.annotations.NullMarked;

View File

@@ -17,4 +17,7 @@
/**
* X.509 client-certificate authentication support.
*/
@NullMarked
package org.springframework.ws.soap.security.x509;
import org.jspecify.annotations.NullMarked;

View File

@@ -50,10 +50,12 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, In
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@SuppressWarnings("NullAway.Init")
private Pattern subjectDNPattern;
private String subjectDNRegex = "CN=(.*?),";
@SuppressWarnings("NullAway.Init")
private UserDetailsService userDetailsService;
// ~ Methods

View File

@@ -17,4 +17,7 @@
/**
* User details popular for X.509 client certificates.
*/
@NullMarked
package org.springframework.ws.soap.security.x509.populator;
import org.jspecify.annotations.NullMarked;