I want to retrieve Common Name (CN) property from client certificate in SOAP communication. I'm using Spring WebServiceTemplate to create my webservice endpoint. I have already implemented WS mutual authentication following the example.
Is there any solution to obtain certificate details from client request by means of WebServiceTemplate or some other library?
Fortunately, I have managed to figure it out! Spring WS provides very convenient way to retrieve the X509Certificate.
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. It can be a MessageContext instance.
public GetCountryResponse getCountry(@RequestPayload MessageContext context, @RequestPayload GetCountryRequest request)`
Then You will be able to obtain the wsse:Security
header as follows:
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:
String binarySecurityToken = elem.getElementsByTagName("BinarySecurityToken").item(0).getTextContent();
At the end, you should recreate the X509Certificate by passing binarySecurityToken as its constructor parameter. Later You can extract CN by many different ways for example by means of LDAP utlis.