I have created a web service in netbeans with METRO. I modified my web service wsit config for using Usernametoken authentication (without encryption).
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="NewWebService" targetNamespace="http://test.org/" xmlns:tns="http://test.org/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
>
<message name="hello"/>
<message name="helloResponse"/>
<portType name="NewWebService">
<operation name="hello">
<input message="tns:hello"/>
<output message="tns:helloResponse"/>
</operation>
</portType>
<binding name="NewWebServicePortBinding" type="tns:NewWebService">
<wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#UsernameToken"/>
<operation name="hello">
<input></input>
<output></output>
</operation>
</binding>
<service name="NewWebService">
<port name="NewWebServicePort" binding="tns:NewWebServicePortBinding"/>
</service>
<!-- Policy for Username Token with plaintext password, sent from client to server only -->
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken=".../IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
<wsss:ValidatorConfiguration wspp:visibility="private" xmlns:wsss="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
<wsss:Validator name="usernameValidator" classname="org.test.MyAuth"/>
</wsss:ValidatorConfiguration>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</definitions>
My PasswordValidator
package org.test;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidationException;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback.Request;
public class MyAuth implements PasswordValidationCallback.PasswordValidator
{
@Override
public boolean validate(Request request) throws PasswordValidationException {
PasswordValidationCallback.PlainTextPasswordRequest ptreq
= (PasswordValidationCallback.PlainTextPasswordRequest)request;
//Database query
return CheckUserInDateBase(ptreq.getPassword(), ptreq.getUsername());
}
}
Now i need authorize user with his username and password and check his role (every method of web service has annotation RolesAllowed). I have created SOAP handler for my web service where I trying to get username and password from soap headers, but header doesnt contains this information (when i get this header in handler).
Actually SOAP message looks like
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<S:Header>
<macAddress xmlns="http://ws.mkyong.com/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next">F8-D1-11-01-36-20</macAddress>
<wsse:Security S:mustUnderstand="1">
<wsse:UsernameToken xmlns:ns15="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity" xmlns:ns14="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns13="http://www.w3.org/2003/05/soap-envelope" wsu:Id="uuid_48e60f1c-aea9-4bcc-897f-ef661fe2895b">
<wsse:Username>myusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<ns2:hello xmlns:ns2="http://test.org/">
<name>aaaa</name>
</ns2:hello>
</S:Body>
</S:Envelope>
When I trying to extract header’s child elements I’m getting only macAddress header (my custom header)
@Override
public boolean handleMessage(SOAPMessageContext context) {
Iterator i = context.getMessage().getSOAPPart().getEnvelope().getHeader().getChildElements();
return true;
}
So. How can I access to wssecurity headers? Or maybe has another way to check user role before execution web service method?
Instead of checking at your validator, store the username and password using ThreadLocal then apply your authentication roles within the service implementation as below. In my case, I used this approach to throw a custom exception.
My Validator:
}
My Service Impl:
Reference:
Retrieve plaintext WS-Security password at service endpoint with Metro + WSIT?