mirror of
https://github.com/spring-projects/spring-security.git
synced 2026-02-08 22:44:35 +00:00
Null safety via JSpecify spring-security-kerberos-client
Closes gh-18552
This commit is contained in:
parent
8247d18122
commit
91aee30906
@ -1,4 +1,5 @@
|
||||
plugins {
|
||||
id 'security-nullability'
|
||||
id 'io.spring.convention.spring-module'
|
||||
id 'javadoc-warnings-error'
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
@ -82,13 +83,13 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
|
||||
private static final Credentials credentials = new NullCredentials();
|
||||
|
||||
private final String keyTabLocation;
|
||||
private final @Nullable String keyTabLocation;
|
||||
|
||||
private final String userPrincipal;
|
||||
private final @Nullable String userPrincipal;
|
||||
|
||||
private final String password;
|
||||
private final @Nullable String password;
|
||||
|
||||
private final Map<String, Object> loginOptions;
|
||||
private final @Nullable Map<String, Object> loginOptions;
|
||||
|
||||
/**
|
||||
* Instantiates a new kerberos rest template.
|
||||
@ -110,7 +111,7 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param keyTabLocation the key tab location
|
||||
* @param userPrincipal the user principal
|
||||
*/
|
||||
public KerberosRestTemplate(String keyTabLocation, String userPrincipal) {
|
||||
public KerberosRestTemplate(@Nullable String keyTabLocation, @Nullable String userPrincipal) {
|
||||
this(keyTabLocation, userPrincipal, buildHttpClient());
|
||||
}
|
||||
|
||||
@ -120,7 +121,8 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param userPrincipal the user principal
|
||||
* @param httpClient the http client
|
||||
*/
|
||||
public KerberosRestTemplate(String keyTabLocation, String userPrincipal, HttpClient httpClient) {
|
||||
public KerberosRestTemplate(@Nullable String keyTabLocation, @Nullable String userPrincipal,
|
||||
HttpClient httpClient) {
|
||||
this(keyTabLocation, userPrincipal, null, null, httpClient);
|
||||
}
|
||||
|
||||
@ -128,7 +130,7 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* Instantiates a new kerberos rest template.
|
||||
* @param loginOptions the login options
|
||||
*/
|
||||
public KerberosRestTemplate(Map<String, Object> loginOptions) {
|
||||
public KerberosRestTemplate(@Nullable Map<String, Object> loginOptions) {
|
||||
this(null, null, null, loginOptions, buildHttpClient());
|
||||
}
|
||||
|
||||
@ -137,7 +139,7 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param loginOptions the login options
|
||||
* @param httpClient the http client
|
||||
*/
|
||||
public KerberosRestTemplate(Map<String, Object> loginOptions, HttpClient httpClient) {
|
||||
public KerberosRestTemplate(@Nullable Map<String, Object> loginOptions, HttpClient httpClient) {
|
||||
this(null, null, null, loginOptions, httpClient);
|
||||
}
|
||||
|
||||
@ -147,7 +149,8 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param userPrincipal the user principal
|
||||
* @param loginOptions the login options
|
||||
*/
|
||||
public KerberosRestTemplate(String keyTabLocation, String userPrincipal, Map<String, Object> loginOptions) {
|
||||
public KerberosRestTemplate(@Nullable String keyTabLocation, @Nullable String userPrincipal,
|
||||
@Nullable Map<String, Object> loginOptions) {
|
||||
this(keyTabLocation, userPrincipal, null, loginOptions, buildHttpClient());
|
||||
}
|
||||
|
||||
@ -158,8 +161,8 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param password the password
|
||||
* @param loginOptions the login options
|
||||
*/
|
||||
public KerberosRestTemplate(String keyTabLocation, String userPrincipal, String password,
|
||||
Map<String, Object> loginOptions) {
|
||||
public KerberosRestTemplate(@Nullable String keyTabLocation, @Nullable String userPrincipal,
|
||||
@Nullable String password, @Nullable Map<String, Object> loginOptions) {
|
||||
this(keyTabLocation, userPrincipal, password, loginOptions, buildHttpClient());
|
||||
}
|
||||
|
||||
@ -171,8 +174,8 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
* @param loginOptions the login options
|
||||
* @param httpClient the http client
|
||||
*/
|
||||
private KerberosRestTemplate(String keyTabLocation, String userPrincipal, String password,
|
||||
Map<String, Object> loginOptions, HttpClient httpClient) {
|
||||
private KerberosRestTemplate(@Nullable String keyTabLocation, @Nullable String userPrincipal,
|
||||
@Nullable String password, @Nullable Map<String, Object> loginOptions, HttpClient httpClient) {
|
||||
super(new HttpComponentsClientHttpRequestFactory(httpClient));
|
||||
this.keyTabLocation = keyTabLocation;
|
||||
this.userPrincipal = userPrincipal;
|
||||
@ -226,9 +229,9 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final <T> T doExecute(final URI url, final String uriTemplate, final HttpMethod method,
|
||||
final RequestCallback requestCallback, final ResponseExtractor<T> responseExtractor)
|
||||
throws RestClientException {
|
||||
protected final <T> T doExecute(final URI url, final @Nullable String uriTemplate,
|
||||
final @Nullable HttpMethod method, final @Nullable RequestCallback requestCallback,
|
||||
final @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
|
||||
|
||||
try {
|
||||
LoginContext lc = buildLoginContext();
|
||||
@ -249,23 +252,28 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T doExecuteSubject(URI url, String uriTemplate, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor) throws RestClientException {
|
||||
return super.doExecute(url, uriTemplate, method, requestCallback, responseExtractor);
|
||||
private <T> T doExecuteSubject(URI url, @Nullable String uriTemplate, @Nullable HttpMethod method,
|
||||
@Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor)
|
||||
throws RestClientException {
|
||||
T result = super.doExecute(url, uriTemplate, method, requestCallback, responseExtractor);
|
||||
if (result == null) {
|
||||
throw new RestClientException("doExecute returned null");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final class ClientLoginConfig extends Configuration {
|
||||
|
||||
private final String keyTabLocation;
|
||||
private final @Nullable String keyTabLocation;
|
||||
|
||||
private final String userPrincipal;
|
||||
private final @Nullable String userPrincipal;
|
||||
|
||||
private final String password;
|
||||
private final @Nullable String password;
|
||||
|
||||
private final Map<String, Object> loginOptions;
|
||||
private final @Nullable Map<String, Object> loginOptions;
|
||||
|
||||
private ClientLoginConfig(String keyTabLocation, String userPrincipal, String password,
|
||||
Map<String, Object> loginOptions) {
|
||||
private ClientLoginConfig(@Nullable String keyTabLocation, @Nullable String userPrincipal,
|
||||
@Nullable String password, @Nullable Map<String, Object> loginOptions) {
|
||||
super();
|
||||
this.keyTabLocation = keyTabLocation;
|
||||
this.userPrincipal = userPrincipal;
|
||||
@ -309,12 +317,12 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
private static class NullCredentials implements Credentials {
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
public @Nullable Principal getUserPrincipal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getPassword() {
|
||||
public char @Nullable [] getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -322,11 +330,11 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
|
||||
private static final class CallbackHandlerImpl implements CallbackHandler {
|
||||
|
||||
private final String userPrincipal;
|
||||
private final @Nullable String userPrincipal;
|
||||
|
||||
private final String password;
|
||||
private final @Nullable String password;
|
||||
|
||||
private CallbackHandlerImpl(String userPrincipal, String password) {
|
||||
private CallbackHandlerImpl(@Nullable String userPrincipal, @Nullable String password) {
|
||||
super();
|
||||
this.userPrincipal = userPrincipal;
|
||||
this.password = password;
|
||||
@ -342,7 +350,9 @@ public class KerberosRestTemplate extends RestTemplate {
|
||||
}
|
||||
else if (callback instanceof PasswordCallback) {
|
||||
PasswordCallback pc = (PasswordCallback) callback;
|
||||
pc.setPassword(this.password.toCharArray());
|
||||
if (this.password != null) {
|
||||
pc.setPassword(this.password.toCharArray());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedCallbackException(callback, "Unknown Callback");
|
||||
|
||||
@ -23,6 +23,7 @@ import javax.security.auth.login.Configuration;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@ -40,9 +41,9 @@ public class SunJaasKrb5LoginConfig extends Configuration implements Initializin
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(SunJaasKrb5LoginConfig.class);
|
||||
|
||||
private String servicePrincipal;
|
||||
private @Nullable String servicePrincipal;
|
||||
|
||||
private Resource keyTabLocation;
|
||||
private @Nullable Resource keyTabLocation;
|
||||
|
||||
private Boolean useTicketCache = false;
|
||||
|
||||
@ -50,7 +51,7 @@ public class SunJaasKrb5LoginConfig extends Configuration implements Initializin
|
||||
|
||||
private Boolean debug = false;
|
||||
|
||||
private String keyTabLocationAsString;
|
||||
private @Nullable String keyTabLocationAsString;
|
||||
|
||||
public void setServicePrincipal(String servicePrincipal) {
|
||||
this.servicePrincipal = servicePrincipal;
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
package org.springframework.security.kerberos.client.config;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@ -29,6 +29,8 @@ import javax.security.auth.login.Configuration;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.ldap.core.support.LdapContextSource;
|
||||
import org.springframework.security.kerberos.client.config.SunJaasKrb5LoginConfig;
|
||||
@ -65,7 +67,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class KerberosLdapContextSource extends DefaultSpringSecurityContextSource implements InitializingBean {
|
||||
|
||||
private Configuration loginConfig;
|
||||
private @Nullable Configuration loginConfig;
|
||||
|
||||
/**
|
||||
* Instantiates a new kerberos ldap context source.
|
||||
@ -108,10 +110,10 @@ public class KerberosLdapContextSource extends DefaultSpringSecurityContextSourc
|
||||
Subject serviceSubject = login();
|
||||
|
||||
final NamingException[] suppressedException = new NamingException[] { null };
|
||||
DirContext dirContext = Subject.doAs(serviceSubject, new PrivilegedAction<>() {
|
||||
DirContext dirContext = Subject.doAs(serviceSubject, new PrivilegedAction<@Nullable DirContext>() {
|
||||
|
||||
@Override
|
||||
public DirContext run() {
|
||||
public @Nullable DirContext run() {
|
||||
try {
|
||||
return KerberosLdapContextSource.super.getDirContextInstance(environment);
|
||||
}
|
||||
@ -125,6 +127,9 @@ public class KerberosLdapContextSource extends DefaultSpringSecurityContextSourc
|
||||
if (suppressedException[0] != null) {
|
||||
throw suppressedException[0];
|
||||
}
|
||||
if (dirContext == null) {
|
||||
throw new NamingException("Failed to obtain DirContext");
|
||||
}
|
||||
|
||||
return dirContext;
|
||||
}
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
package org.springframework.security.kerberos.client.ldap;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
package org.springframework.security.kerberos.client;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
Loading…
x
Reference in New Issue
Block a user