as title, How can I obtain the username from soapheader to perform further action?
I already use SimplePasswordValidationCallbackHandler to do the authenticaiton successfully, then I need to get back the username to perform other validation.
Printable View
as title, How can I obtain the username from soapheader to perform further action?
I already use SimplePasswordValidationCallbackHandler to do the authenticaiton successfully, then I need to get back the username to perform other validation.
You could obtain the authenticated user from the Spring Security Context. See below.
Code:Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
String username = currentUser.getName();
I have recently done this using an Interceptor, in fact wanted to do the same in an Endpoint but don't have access to the SOAP header data in an Endpoint as far as I know.
Here is how I did it, note the Optional class is from Google Guava:
Code:public class UsernameInterceptor implements EndpointInterceptor {
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
WebServiceMessage message = messageContext.getRequest();
if (message instanceof SoapMessage) {
SoapMessage soapMessage = (SoapMessage)message;
Optional<String> soapUserName = getSoapUserName(soapMessage);
}
/**
* Get the Username, contained within a Security and in turn UsernameToken element.
*
* @param soapMessage the SoapMessage instance to be inspected
* @return the Optional<String> instance containing the SOAP Username
*/
protected Optional<String> getSoapUserName(SoapMessage soapMessage) {
Assert.notNull(soapMessage);
Iterator<SoapHeaderElement> iterator = soapMessage.getEnvelope().getHeader().examineAllHeaderElements();
while(iterator.hasNext()) {
SoapHeaderElement header = iterator.next();
String headerName = header.getName().getLocalPart();
if(headerName.equalsIgnoreCase("Security")) {
DOMSource domSource = (DOMSource) header.getSource();
Node securityNode = domSource.getNode();
NodeList securityNodeChildren = securityNode.getChildNodes();
for (int i = 0; i < securityNodeChildren.getLength(); i++) {
Node childNode = securityNodeChildren.item(i);
if (childNode.getLocalName() != null && childNode.getLocalName().equalsIgnoreCase("UsernameToken")) {
NodeList usernameTokenChildren = childNode.getChildNodes();
for (int j = 0; j < usernameTokenChildren.getLength(); j++) {
Node userNameTokenChild = usernameTokenChildren.item(j);
if (userNameTokenChild.getLocalName() != null && userNameTokenChild.getLocalName().equalsIgnoreCase("Username")) {
String userNameCandidate = userNameTokenChild.getTextContent();
if (StringUtils.hasLength(userNameCandidate)) {
return Optional.of(userNameCandidate);
} else {
return Optional.absent();
}
}
}
}
}
}
}
return Optional.absent();
}
Thanks ndewet,
In your interceptor, once you determined the username, how do you makes externally visible, i.e. to the endpoint? For example did you add a new element to the header?
Regards,
kevin