Spring Security Remoting provides security services for remote method invocation in distributed Spring applications including RMI context propagation, HTTP invoker authentication, and DNS resolution utilities.
—
BASIC authentication support for Spring's HTTP invoker remoting. Automatically extracts credentials from SecurityContextHolder and adds them as HTTP BASIC authentication headers to remote method calls.
Deprecation Notice: HTTP invoker authentication APIs are deprecated as of Spring Security 5.6.0 with no replacement.
Extends Spring's SimpleHttpInvokerRequestExecutor to add BASIC authentication support using credentials from the current SecurityContext.
public class AuthenticationSimpleHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {
/**
* Called every time a HTTP invocation is made.
* Sets up the connection and adds an Authorization HTTP header for BASIC authentication.
* Uses SecurityContextHolder to obtain the relevant principal and credentials.
* @param con the HTTP connection to prepare
* @param contentLength the length of the content to send
* @throws IOException if thrown by HttpURLConnection methods
*/
protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException;
/**
* Extension point for subclasses to perform additional configuration.
* Called after authentication headers are set.
* @param con the HTTP connection to prepare
* @param contentLength the length of the content to send
* @throws IOException if thrown by HttpURLConnection methods
*/
protected void doPrepareConnection(HttpURLConnection con, int contentLength) throws IOException;
}import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor;
import org.springframework.security.authentication.AuthenticationTrustResolver;
// Define your service interface
public interface MyRemoteService {
String processRequest(String input);
List<String> getDataList();
}
// Configure HTTP invoker proxy with authentication
HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
proxy.setServiceUrl("http://localhost:8080/remoting/MyRemoteService");
proxy.setServiceInterface(MyRemoteService.class);
// Add authentication support
AuthenticationSimpleHttpInvokerRequestExecutor executor =
new AuthenticationSimpleHttpInvokerRequestExecutor();
proxy.setHttpInvokerRequestExecutor(executor);
// Get the proxy instance
MyRemoteService service = (MyRemoteService) proxy.getObject();
// Use the service - authentication will be handled automatically
String result = service.processRequest("test data");<!-- HTTP Invoker Proxy with Authentication -->
<bean id="myRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/remoting/MyRemoteService"/>
<property name="serviceInterface" value="com.example.MyRemoteService"/>
<property name="httpInvokerRequestExecutor" ref="authHttpInvokerRequestExecutor"/>
</bean>
<!-- Authentication-enabled Request Executor -->
<bean id="authHttpInvokerRequestExecutor"
class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor"/>import org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor;
import java.net.HttpURLConnection;
import java.io.IOException;
public class CustomHttpInvokerRequestExecutor extends AuthenticationSimpleHttpInvokerRequestExecutor {
@Override
protected void doPrepareConnection(HttpURLConnection con, int contentLength) throws IOException {
// Add custom headers after authentication is set up
con.setRequestProperty("X-Client-Version", "1.0");
con.setRequestProperty("X-Request-ID", generateRequestId());
// Set custom timeout
con.setConnectTimeout(5000);
con.setReadTimeout(30000);
}
private String generateRequestId() {
return "REQ-" + System.currentTimeMillis();
}
}import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
// Set up authentication in SecurityContext before making remote calls
Authentication auth = new UsernamePasswordAuthenticationToken("username", "password");
SecurityContextHolder.getContext().setAuthentication(auth);
try {
// Remote call will automatically include BASIC authentication
MyRemoteService service = getMyRemoteService(); // configured with AuthenticationSimpleHttpInvokerRequestExecutor
String result = service.processRequest("secure data");
System.out.println("Result: " + result);
} finally {
// Clean up security context
SecurityContextHolder.clearContext();
}The AuthenticationSimpleHttpInvokerRequestExecutor automatically:
Basic base64(username:password)Authorization header to the HTTP connectionFor authentication to be applied, the SecurityContext must contain an Authentication that:
The generated Authorization header follows HTTP BASIC authentication standard:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=Where the value after "Basic " is Base64-encoded username:password.
The executor provides debug logging to help troubleshoot authentication:
The server-side HTTP invoker service exporter should be configured to handle BASIC authentication, typically through Spring Security's HTTP security configuration:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/remoting/**").authenticated()
.anyRequest().permitAll()
)
.httpBasic(Customizer.withDefaults())
.build();
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-security--spring-security-remoting