I have created a simple EJB3 project and exposed it as a web service (your typical Echo
service). I'm using WSSE UsernameToken headers in the SOAP requests to send
authentication info. I can successfully authenticate using a username and digesting the
password (e.g. Base64 encode of the SHA-1 hash).
However, when I encorporate the Created node and add to the digest I get an "Invalid
User" exception. But, I can use just the hash of the password (without the created
node) and authenticate successfully. According to the docs from the OASIS site the digest
is computed as (taken from Web Services Security UsernameToken Profile):
| Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
|
I'm currently not using a Nonce since the spec says that both the Nonce and the
Created are optional.
It's as if the server is ignoring the fact that the created node exists. I'm not
fully confident that I have the jboss-wsse-server.xml file set up or even the security
header. See below for the appropriate files. Any thoughts would be appreciated.
EJB3 Service:
| package com.test;
|
| import javax.annotation.security.RolesAllowed;
| import javax.ejb.Stateless;
| import javax.jws.WebMethod;
| import javax.jws.WebParam;
| import javax.jws.WebResult;
| import javax.jws.WebService;
|
| import org.jboss.ws.annotation.EndpointConfig;
|
| @Stateless
| @WebService(endpointInterface = "com.test.IEchoSession",
serviceName="EchoService", portName="EchoServiceSOAP")
| @EndpointConfig(configName = "Standard WSSecurity Endpoint")
| public class EchoSession implements IEchoSession {
|
| /**
| *
| */
| private static final long serialVersionUID = 1L;
|
| @Override
| @WebMethod(operationName="Echo")
| @WebResult(partName="EchoResponse")
| @RolesAllowed(value={"friend"})
| public String echo(@WebParam(partName="text") String text) {
| return "You said: " + text;
| }
|
| }
|
jboss.xml (in the EJB3 META-INF folder):
<?xml version="1.0" encoding="utf-8"?>
| <jboss>
| <security-domain>java:/jaas/MyRealm</security-domain>
| <webservices>
| <context-root>/echo</context-root>
| </webservices>
| <enterprise-beans>
| <session>
| <ejb-name>EchoSession</ejb-name>
| <port-component>
| <port-component-name>EchoSession</port-component-name>
| <port-component-uri>/EchoService</port-component-uri>
| <transport-guarantee>NONE</transport-guarantee>
| <secure-wsdl-access>false</secure-wsdl-access>
| </port-component>
| </session>
| </enterprise-beans>
|
| </jboss>
jboss-wsse-server.xml (also in the META-INF):
<jboss-ws-security
xmlns="http://www.jboss.com/ws-security/config"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xsi:schemaLocation="http://www.jboss.com/ws-security/config
|
http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
| <config>
| <username/>
| <timestamp ttl="300"/>
| <timestamp-verification createdTolerance="100"
warnCreated="false" expiresTolerance="100"
warnExpires="false" />
| <authenticate>
| <usernameAuth/>
| </authenticate>
| </config>
| </jboss-ws-security>
|
On the client side (flex component) the following header get's added to the request:
| private function addWSSEHeader(): SOAPHeader {
|
| var date : Date = new Date();
| _ds = getDateString(date);
| date.minutes += 3;
|
| var plain : String = SHA1.hashToBase64(password.text);
|
| _password = SHA1.hashToBase64(_ds + password.text);
|
| trace("plain: " + plain);
| trace("timestamp " + _password);
| var usernameTokenXML:XML =
| <wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-...
|
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...
| <wsu:Timestamp
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...
| <wsu:Created>{_ds}</wsu:Created>
| <wsu:Expires>{getDateString(date)}</wsu:Expires>
| </wsu:Timestamp>
| <wsse:UsernameToken>
| <wsse:Username
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecu...
| <wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-userna...
|
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-...
| <wsu:Created>{_ds}</wsu:Created>
| </wsse:UsernameToken>
| </wsse:Security>
|
| var wsse: Namespace = new
Namespace("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...;
| var wsseSecurity: QName = new QName(wsse.uri, "Security");
| var header: SOAPHeader = new SOAPHeader(wsseSecurity,
{"wsse":"Security"});
| header.content = usernameTokenXML;
|
| return header;
| }
|
|
And here is an example of the SOAP message:
| <SOAP-ENV:Envelope
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><SOAP...
xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...
xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ws...
| <wsu:Timestamp>
| <wsu:Created>2009-09-25T13:07:29Z</wsu:Created>
| <wsu:Expires>2009-09-25T13:10:29Z</wsu:Expires>
| </wsu:Timestamp>
| <wsse:UsernameToken>
| <wsse:Username
Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecur...
| <wsse:Password
Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-usernam...
| <wsu:Created>2009-09-25T13:07:29Z</wsu:Created>
| </wsse:UsernameToken>
| </wsse:Security></SOAP-ENV:Header><SOAP-ENV:Body>
| <tns:echo
xmlns:tns='http://test.com/'>
| <arg0>test</arg0>
| </tns:echo>
| </SOAP-ENV:Body></SOAP-ENV:Envelope>
|
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4257096#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...