Hi,
I'm using XWSS/WSIT libaries under Tomcat to develop secured web service, with multiuser authorization.
Username/Password params are authorized in the EnvironmentHandler.
The username value is send in SOAP message, in tag <wsse:Username>Username</wsse:Username>
Sample SOAP:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-1198013990123493230040">
<wsse:Username>Abc</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">/2qvu+vlFRV2HAhAM8rIFJpF</wsse:Nonce>
<wsu:Created>2007-12-18T21:39:50.342Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<ns2:sayHello xmlns:ns2="http://ws/">
<arg0>Hello</arg0>
</ns2:sayHello>
</S:Body>
</S:Envelope>
After successful authorization, I would like to get username value in my @WebService class,
how can i do that?
Here is my sample server code:
SecurityHandler:
package ws.security;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.FileInputStream;
import java.io.File;
import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.SubjectAccessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSecurityException;
import java.util.HashSet;
import java.net.Socket;
import javax.xml.ws.handler.MessageContext;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
public class SecurityHandler implements SOAPHandler<SOAPMessageContext> {
private final static String CFG_PATH = "../webapps/xhell/WEB-INF/server/cfg";
private final static String CONFIG = "user-pass-authenticate-server.xml";
private XWSSProcessor processor = null;
public SecurityHandler() {
FileInputStream serverConfig = null;
try {
serverConfig = new FileInputStream(new File(CFG_PATH+"/"+CONFIG));
XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
processor = factory.createProcessorForSecurityConfiguration(serverConfig, new ServerSecurityEnvironmentHandler());
serverConfig.close();
} catch (Exception e) {
throw new RuntimeException("Cannot create SecurityHandler instance");
}
}
public Set<QName> getHeaders(){
QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "");
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
public boolean handleFault(SOAPMessageContext messageContext) {
return true;
}
public boolean handleMessage(SOAPMessageContext messageContext) {
secureServer(messageContext);
return true;
}
public void close(MessageContext messageContext) {
}
private void secureServer(SOAPMessageContext messageContext) {
Boolean outMessageIndicator;
outMessageIndicator= (Boolean)messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = messageContext.getMessage();
if (outMessageIndicator.booleanValue())
return;
try{
ProcessingContext context = processor.createProcessingContext(message);
context.getExtraneousProperties().putAll(messageContext);
context.setSOAPMessage(message);
SOAPMessage verifiedMsg= null;
verifiedMsg= processor.verifyInboundMessage(context);
messageContext.setMessage(verifiedMsg);
} catch (Exception ex) {
Socket client = null;
ServletRequest requset = (ServletRequest)messageContext.get(MessageContext.SERVLET_REQUEST);
try {
client = new Socket(requset.getRemoteAddr(), requset.getRemotePort());
}catch(Exception e) {
}
throw new WebServiceException("Authorization failed");
}
}
}
EnvironmentHandler:
package ws.security;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class ServerSecurityEnvironmentHandler implements CallbackHandler {
//column 0 valid usernames
//column 1 usernames passwords
private String[][] validUsers = {
{"Abc","cde"},
{"efG","hIj"},
{"user","haslo"}
};
public void handle(Callback[] call) throws IOException, UnsupportedCallbackException {
for(int i=0; i<call.length; i++) {
if(call[i] instanceof PasswordValidationCallback) { //passwordValidation
PasswordValidationCallback passCallback = (PasswordValidationCallback)call;
if(passCallback.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {
passCallback.setValidator(new PlainTextPasswordValidator());
} else if(passCallback.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {
PasswordValidationCallback.DigestPasswordRequest request;
request = (PasswordValidationCallback.DigestPasswordRequest)passCallback.getRequest();
String username = request.getUsername();
for(int j=0; j<validUsers.length; j++) {
if(username.equals(validUsers[j][0])) {
request.setPassword(validUsers[j][1]);
passCallback.setValidator(new PasswordValidationCallback.DigestPasswordValidator());
break;
}
}
}
} else {
throw new UnsupportedCallbackException(call[i],"Unsupported Callback");
}
}
}
private class PlainTextPasswordValidator implements PasswordValidationCallback.PasswordValidator {
public boolean validate(PasswordValidationCallback.Request request)
throws PasswordValidationCallback.PasswordValidationException {
PasswordValidationCallback.PlainTextPasswordRequest plain;
plain = (PasswordValidationCallback.PlainTextPasswordRequest)request;
String username = plain.getUsername();
String password = plain.getPassword();
for(int i=0; i<validUsers.length; i++) {
if(username.equals(validUsers[i][0]) && password.equals(validUsers[i][1]))
return true;
}
return false;
}
}
}
And WebService class:
package ws;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.HandlerChain;
import javax.annotation.Resource;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
@WebService
@HandlerChain(file="../server/cfg/handler.xml")
public class XHello {
@Resource
private WebServiceContext wsContext;
@WebMethod
public String sayHello() {
return "Hello";
}
}
I would like to get username value in sayHello method.
(Sorry for my bad english)