You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WebServiceTemplate的SOAP调用中集成spring.security.oauth2.client

为WebServiceTemplate添加Keycloak认证令牌

1. 配置OAuth2客户端获取令牌

先在Spring Boot中配置Keycloak作为OAuth2客户端,借助Spring Security OAuth2 Client的自动配置来管理令牌的获取与刷新。

在application.yml中添加配置:

spring:
  security:
    oauth2:
      client:
        registration:
          keycloak-soap:
            client-id: 你的客户端ID
            client-secret: 你的客户端密钥
            authorization-grant-type: client_credentials
            scope: openid, soap-api-access
        provider:
          keycloak-soap:
            token-uri: https://你的Keycloak域名/auth/realms/你的领域/protocol/openid-connect/token

2. 实现令牌获取服务

用Spring Security提供的OAuth2AuthorizedClientManager来获取有效访问令牌,它会自动处理令牌缓存和过期刷新:

import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.request.OAuth2AuthorizeRequest;
import org.springframework.stereotype.Service;

@Service
public class KeycloakTokenService {

    private final OAuth2AuthorizedClientManager authorizedClientManager;

    public KeycloakTokenService(OAuth2AuthorizedClientManager authorizedClientManager) {
        this.authorizedClientManager = authorizedClientManager;
    }

    public String getAccessToken() {
        OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("keycloak-soap")
                .principal("soap-client")
                .build();
        OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest);
        return authorizedClient.getAccessToken().getTokenValue();
    }
}

3. 自定义WebServiceMessageCallback添加认证头

创建自定义的WebServiceMessageCallback,在请求发送前注入Authorization头:

import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.soap.SoapMessage;
import javax.xml.transform.TransformerException;
import java.io.IOException;

public class SoapAuthHeaderCallback implements WebServiceMessageCallback {

    private final String accessToken;

    public SoapAuthHeaderCallback(String accessToken) {
        this.accessToken = accessToken;
    }

    @Override
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
        if (message instanceof SoapMessage soapMessage) {
            soapMessage.getSoapHeader().addHeaderElement(javax.xml.namespace.QName.valueOf("Authorization"))
                    .setText("Bearer " + accessToken);
        }
    }
}

4. 在WebServiceTemplate调用中应用认证

注入KeycloakTokenService和WebServiceTemplate,调用SOAP接口时传入自定义的Callback:

import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceTemplate;

@Service
public class SoapClientService {

    private final WebServiceTemplate webServiceTemplate;
    private final KeycloakTokenService tokenService;

    public SoapClientService(WebServiceTemplate webServiceTemplate, KeycloakTokenService tokenService) {
        this.webServiceTemplate = webServiceTemplate;
        this.tokenService = tokenService;
    }

    public Object callSoapService(Object requestPayload) {
        String accessToken = tokenService.getAccessToken();
        return webServiceTemplate.marshalSendAndReceive(
                "https://外部SOAP服务地址",
                requestPayload,
                new SoapAuthHeaderCallback(accessToken)
        );
    }
}

关键注意事项

  • 如果使用用户授权模式(authorization_code),需替换authorization-grant-type并处理当前登录用户的上下文,此时principal要传入用户相关信息。
  • OAuth2AuthorizedClientManager会自动缓存令牌,避免重复请求Keycloak,令牌过期时会自动触发刷新。
  • 确保Keycloak客户端配置的scope包含外部SOAP服务要求的权限。

内容的提问来源于stack exchange,提问作者Eljah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:36:30