简体   繁体   English

如何在 WebServiceTemplate 中检索有关证书的信息?

[英]How to retrieve information about certificate in WebServiceTemplate?

I want to retrieve Common Name<\/em> (CN) property from client certificate in SOAP communication.我想在 SOAP 通信中从客户端证书中检索公用名<\/em>(CN) 属性。 I'm using Spring WebServiceTemplate<\/strong> to create my webservice endpoint.我正在使用 Spring WebServiceTemplate<\/strong>创建我的 web 服务端点。 I have already implemented WS mutual authentication following the example<\/a> .我已经按照示例<\/a>实现了 WS 相互认证。

Is there any solution to obtain certificate details<\/strong> from client request by means of WebServiceTemplate or some other library?是否有任何解决方案可以通过 WebServiceTemplate 或其他库从客户端请求中获取证书详细信息<\/strong>?

"

Fortunately, I have managed to figure it out! 幸运的是,我设法弄清楚了! Spring WS provides very convenient way to retrieve the X509Certificate. Spring WS提供了一种非常方便的方法来检索X509证书。

Normally, You have an endpoint like this: 通常,您具有以下端点:

@Endpoint
public class CountryEndpoint {
    private static final String NAMESPACE_URI = "http://spring.io/guides/gs-producing-web-service";

    ...

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
    @ResponsePayload
    public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) {
        //method body here
        return response;
    }
}

However, Spring allows to add additional parameters the method annotated as @PayloadRoot . 但是,Spring允许使用注释为@PayloadRoot的方法添加其他参数。 It can be a MessageContext instance. 它可以是MessageContext实例。

public GetCountryResponse getCountry(@RequestPayload MessageContext context, @RequestPayload GetCountryRequest request)`

Then You will be able to obtain the wsse:Security header as follows: 然后,您将能够获得wsse:Security标头,如下所示:

WebServiceMessage webServiceMessageRequest = context.getRequest(); 
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) webServiceMessageRequest;
SOAPMessage doc = saajSoapMessage.getSaajMessage();
Element elem = WSSecurityUtil.getSecurityHeader(doc.getSOAPPart(), "");

Now get the right content of BinarySecurityToken tag: 现在获取BinarySecurityToken标记的正确内容:

String binarySecurityToken = elem.getElementsByTagName("BinarySecurityToken").item(0).getTextContent(); 

At the end, you should recreate the X509Certificate by passing binarySecurityToken as its constructor parameter. 最后,您应该通过传递binarySecurityToken作为其构造函数参数来重新创建X509Certificate。 Later You can extract CN by many different ways for example by means of LDAP utlis. 以后,您可以通过许多不同的方式来提取CN,例如通过LDAP utlis。

There is another way.还有另一种方法。

  1. Create AbstractSoapInterceptor with this body :使用此主体创建 AbstractSoapInterceptor :
    private final static QName SECURITY_QNAME = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "");
    private static CertificateFactory certFactory;
    public xxx() throws CertificateException {
        super(Phase.PRE_PROTOCOL);
        certFactory = CertificateFactory.getInstance("X.509");
    }
    @SneakyThrows
    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        SoapHeader header = (SoapHeader) message.getHeader(SECURITY_QNAME);
        Node binarySignatureTag = ((Element) header.getObject()).getFirstChild();
        BinarySecurity token = new X509Security((Element) binarySignatureTag, new BSPEnforcer());
        InputStream in = new ByteArrayInputStream(token.getToken());
        X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in);
    }
  1. Register it in configuration of endpoint :在端点配置中注册它:
    @Bean
    public Endpoint endpoint() throws CertificateException {
        EndpointImpl endpoint = new EndpointImpl(springBus(), xxxPortType());
        endpoint.setServiceName(xxxService().getServiceName());
        endpoint.publish("/xxxx");
        endpoint.getInInterceptors().add(new xxx());
        return endpoint;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM