View Full Version : secureOutboundMessage(context) does nothing
res1st
Jun 20th, 2006, 06:56 AM
Hi,
i've looked in the airline example and i want to create a secure echo web service. :)
I wrote a little test client (99% the same as the saaj airline client).
But it doesn't add the security header, that's why i get this error message:
Received SOAP Fault
SOAP Fault Code :SOAP-ENV:Client
SOAP Fault String :com.sun.xml.wss.XWSSecurityException: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found
The dump shows that there is really no security header. Any idea why?
20.06.2006 13:53:14 com.sun.xml.wss.impl.filter.DumpFilter process
INFO: ==== Sending Message Start ====
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<tns:secureEchoRequest xmlns:tns="http://springws.cas.de">halloIngo</tns:secureEchoRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
==== Sending Message End ====
The securityPolicy.xml is the same as in the airline client.
Cheers,
Ingo
Arjen Poutsma
Jun 20th, 2006, 10:15 AM
That's weird. Are you sure you used the exact stept as in the SAAJ GetFrequentFlyerMileage? You have to be sure that you send the return value of the secureMessage method, not the original, un-encrypted version.
Send me (or paste it here) the Java code if you want more help.
res1st
Jun 21st, 2006, 12:34 AM
No problem. This is the code.
package de.cas.springws.webservice;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackEx ception;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;
public class SecureEchoWSTest extends TestCase {
static {
PropertyConfigurator.configure(SecureEchoWSTest.cl ass.getResource("/resources/test/log4j.properties"));
}
/** Logger for SecureEchoWSTest. */
private static final Logger LOG = Logger.getLogger(SecureEchoWSTest.class);
public static final String NAMESPACE_URI = "http://springws.cas.de";
public static final String PREFIX = "tns";
private SOAPConnectionFactory connectionFactory;
private MessageFactory messageFactory;
private URL url;
private XWSSProcessorFactory processorFactory;
protected void setUp() throws Exception {
super.setUp();
connectionFactory = SOAPConnectionFactory.newInstance();
messageFactory = MessageFactory.newInstance();
processorFactory = XWSSProcessorFactory.newInstance();
this.url = new URL("http://localhost:8080/springws/services");
}
public void testSecureEcho() throws SOAPException, IOException, XWSSecurityException {
String username = "Britta Glatt";
String password = "b";
SOAPMessage request = createSecureEchoRequest();
request = secureMessage(request, username, password);
SOAPConnection connection = connectionFactory.createConnection();
SOAPMessage response = connection.call(request, url);
if (!response.getSOAPBody().hasFault()) {
SOAPBodyElement echo = (SOAPBodyElement) response.getSOAPBody().getChildElements().next();
LOG.info("Echo is " + echo.getValue());
} else {
SOAPFault fault = response.getSOAPBody().getFault();
LOG.error("Received SOAP Fault");
LOG.error("SOAP Fault Code :" + fault.getFaultCode());
LOG.error("SOAP Fault String :" + fault.getFaultString());
}
}
private SOAPMessage createSecureEchoRequest() throws SOAPException {
SOAPMessage message = messageFactory.createMessage();
// I'm using payload mapping, not soap action.
// message.getMimeHeaders().addHeader("SOAPAction", "\"http://springws.cas.de/springws/services/secureEcho\"");
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name secureEchoRequestName = envelope.createName("secureEchoRequest", PREFIX, NAMESPACE_URI);
SOAPBodyElement requestElement = message.getSOAPBody().addBodyElement(secureEchoReq uestName);
requestElement.addTextNode("helloIngo");
return message;
}
private SOAPMessage secureMessage(SOAPMessage message, final String username, final String password)
throws IOException, XWSSecurityException {
CallbackHandler callbackHandler = new CallbackHandler() {
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
LOG.debug("Callback handler for securing message got callback!");
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof UsernameCallback) {
UsernameCallback callback = (UsernameCallback) callbacks[i];
callback.setUsername(username);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback callback = (PasswordCallback) callbacks[i];
callback.setPassword(password);
} else {
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
};
InputStream policyStream = null;
XWSSProcessor processor = null;
try {
policyStream = getClass().getResourceAsStream("/deployment/web/WEB-INF/securityPolicy.xml");
processor = processorFactory.createProcessorForSecurityConfigu ration(policyStream, callbackHandler);
} finally {
if (policyStream != null) {
policyStream.close();
}
}
ProcessingContext context = processor.createProcessingContext(message);
SOAPMessage secureMessage = processor.secureOutboundMessage(context);
// verify the secured message.
// ProcessingContext verifyContext = new ProcessingContext();
// verifyContext.setSOAPMessage(secureMessage);
//
// SOAPMessage verifiedMsg = null;
// try {
// verifiedMsg = processor.verifyInboundMessage(verifyContext);
// System.out.println("\nRequester Subject " + SubjectAccessor.getRequesterSubject(context));
// } catch (Exception ex){
// System.err.println("verify error:");
// ex.printStackTrace();
// System.err.println(verifyContext.getSOAPMessage(). toString());
// }
return secureMessage;
}
}
Ingo
Arjen Poutsma
Jun 21st, 2006, 04:45 AM
Hmm. That code looks good. Are you sure the securityPolicy.xml contains a UsernameToken? (Not a RequireUsernameToken, that's for the server-side).
<xwss:SecurityConfiguration dumpMessages="true" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:UsernameToken digestPassword="true" useNonce="true"/>
</xwss:SecurityConfiguration>
Note that you can enable the dumpMessage attribute, to dump the SOAP messages to the log (both on the server and client side). That could help debugging somewhat.
res1st
Jun 21st, 2006, 10:16 AM
Are you sure the securityPolicy.xml contains a UsernameToken? (Not a RequireUsernameToken, that's for the server-side).
That was the problem. :(
I still have the problem that the authentication is working, but not the authorization. But this is ACEGI problem i think.
Is the authorization working in the airline example? (I can't compile it to test it)
Try it by change the role ROLE_FREQUENT_FLYER in the methodSecurityInterceptor.
Cheers,
Ingo
Arjen Poutsma
Jun 21st, 2006, 11:21 AM
That was the problem. :(
Good! It's nice to know that is has been solved. :)
I still have the problem that the authentication is working, but not the authorization. But this is ACEGI problem i think.
Is the authorization working in the airline example? (I can't compile it to test it)
It is working in the sample. Why isn't the sample compiling for you? It should resolve all dependencies...
The basic idea is to make sure you principal carries the role you need in its granted authorities. In the sample, this is accomplished by creating special org.springframework.ws.samples.airline.security.Fr equentFlyerDetails objects, which contains the role (ROLE_FREQUENT_FLYER). The role name is then used by the methodSecurityInterceptor.
But I am no Acegi expert. I basically put the airline sample together from a sample I had lying around :). If you do have more Acegi-related questions, you can visit the Acegi forum (http://forum.springframework.org/forumdisplay.php?f=33).
res1st
Jun 22nd, 2006, 02:01 AM
Hi Arjen.
Why isn't the sample compiling for you? It should resolve all dependencies...
[...snipp...]
found [ org.springframework | spring-mock | 1.2.8 ] in spring-projects
:: resolution report ::
:: evicted modules:
[ apache | xerces | 2.0.2 ] by [[ apache | xerces | 2.8.0 ]] in [global]
[ xml-apis | xml-apis | 1.0.b2 ] by [[ xml-apis | xml-apis | 2.0.2 ]] in [global]
[ org.springframework | spring-oxm | 1.0-m1-20060611203755 ] by [[ org.springframework | spring-oxm | 1.0-m1-200
60612141738 ]] in [global]
[ joda-time | joda-time | 1.2 ] by [[ joda-time | joda-time | 1.2.1 ]] in [global]
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| global | 56 | 3 | 0 | 4 || 52 | 0 |
| buildtime | 1 | 0 | 0 | 0 || 1 | 0 |
| test | 5 | 0 | 0 | 0 || 5 | 0 |
---------------------------------------------------------------------
:: problems summary ::
ERROR: Server access Error: Connection timed out: connect url=https://svn.sourceforge.net/svnroot/springframewor
k/repos/repo-ext/apache/xerces/ivy-2.0.2.xml
ERROR: Server access Error: Connection timed out: connect url=https://svn.sourceforge.net/svnroot/springframewor
k/repos/repo-ext/apache/xerces/2.0.2/xerces-2.0.2.jar
ERROR: Server access Error: Connection timed out: connect url=http://mirrors.dotsrc.org/maven2/apache/xerces/2.0
.2/xerces-2.0.2.pom
ERROR: Server access Error: Connection timed out: connect url=http://mirrors.dotsrc.org/maven2/apache/xerces/2.0
.2/xerces-2.0.2.jar
ERROR: Server access Error: Connection timed out: connect url=http://ivyrep.jayasoft.org/apache/xerces/ivy-2.0.2
.xml
ERROR: Server access Error: Connection timed out: connect url=http://www.ibiblio.org/maven/xerces/jars/xerces-2.
0.2.jar
WARN: module not found: [ apache | xerces | 2.0.2 ]
WARN: filesystem-repo: tried C:\download\web services\spring-ws-1.0-m1\projects\common-build/../reposi
tory/apache/xerces/ivy-2.0.2.xml
WARN: filesystem-repo: tried artifact [ apache | xerces | 2.0.2 ]/xerces.jar[jar]:
WARN: C:\download\web services\spring-ws-1.0-m1\projects\common-build/../repository/apache/xer
ces/2.0.2/xerces-2.0.2.jar
WARN: spring-repo-ext: tried https://svn.sourceforge.net/svnroot/springframework/repos/repo-ext/apache
/xerces/ivy-2.0.2.xml
WARN: spring-repo-ext: tried artifact [ apache | xerces | 2.0.2 ]/xerces.jar[jar]:
WARN: https://svn.sourceforge.net/svnroot/springframework/repos/repo-ext/apache/xerces/2.0.2/x
erces-2.0.2.jar
WARN: dotsrc-maven2-repo: tried http://mirrors.dotsrc.org/maven2/apache/xerces/2.0.2/ivy-2.0.2.xml
WARN: dotsrc-maven2-repo: tried artifact [ apache | xerces | 2.0.2 ]/xerces.jar[jar]:
WARN: http://mirrors.dotsrc.org/maven2/apache/xerces/2.0.2/xerces-2.0.2.jar
WARN: ivyrep: tried http://ivyrep.jayasoft.org/apache/xerces/ivy-2.0.2.xml
WARN: ivyrep: tried artifact [ apache | xerces | 2.0.2 ]/xerces.jar[jar]:
WARN: http://www.ibiblio.org/maven/xerces/jars/xerces-2.0.2.jar
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: circular dependency found ! [ jaxen | jaxen | 1.1-beta-8 ] depends on [ xom | xom | 1.0b3 ] which is alre
ady on the same branch of dependency
WARN: ::::::::::::::::::::::::::::::::::::::::::::::
WARN: :: UNRESOLVED DEPENDENCIES ::
WARN: ::::::::::::::::::::::::::::::::::::::::::::::
WARN: :: [ apache | xerces | 2.0.2 ]: not found
WARN: ::::::::::::::::::::::::::::::::::::::::::::::
I'm behind the firewall and it's possible that this is the problem.
The basic idea is to make sure you principal carries the role you need in its granted authorities. In the sample, this is accomplished by creating special org.springframework.ws.samples.airline.security.Fr equentFlyerDetails objects, which contains the role (ROLE_FREQUENT_FLYER). The role name is then used by the methodSecurityInterceptor.
Yes, ACEGI has a good documentation... :)
My UserDetails object has a assigned role and the role ist set at methodSecurityInterceptor for my web service and my business logic methods. But it doesn't work.
I've set log4j.category.org.springframework=DEBUG but i see no log message of a MethodSecurityInterceptor and i assume, there should be one.
Only the authentication takes place and i also get a log-message:
53261 [http-8080-Processor23] DEBUG acegi.AcegiDigestPasswordValidationCallbackHandler - Authentication success: org.acegisecurity.providers.UsernamePasswordAuthen ticationToken@7af39d: Username: de.cas.springws.webservice.security.CasUserDetails @7af3e0; Password: [PROTECTED]; Authenticated: false; Details: null; Not granted any authorities
I learned that my user is authenticated, although the "Authenticated: false" log message. If i also understand ACEGI right, then "Not granted any authorities" is also correct because i doesn't use the Run-As Manager. But i see nowhere a message of my methodSecurityInterceptor and it doesn't matter which role i add to it. The Methods are always callable for the user, independant of his role. I'll invest some more time today.
Ingo
Update:
ACEGI has the package org.acegisecurity and not org.springframework.
I think i've missed to add a proxy. Sometimes i'm really a fool.
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.