Problem verifying signed mail with bouncycastle API only in axis2 webservice environment - email

here's my very strange problem :
I wrote a ws that checks a signed mail with bouncycastle API. When I test the method outside axis2 environment, all works fine. As soon as i've deployed the ws in tomcat, all goes wrong. I've got a strange exception that I've localized in the bc api, in the readObject() method, when the api try to cast the mime message to asn1 structure.
Here's the exception :
Caused by: org.bouncycastle.cms.CMSException: IOException reading content.
at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
at org.bouncycastle.cms.CMSSignedData.<init>(Unknown Source)
at org.bouncycastle.mail.smime.SMIMESigned.<init>(Unknown Source)
... 32 more
Caused by: java.io.EOFException: EOF found when length expected
at org.bouncycastle.asn1.ASN1InputStream.readLength(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.readLength(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source
The exception is raised when i call the SignedMailValidator constructor.
private static SignBean verifySignedMail(MimeMessage msg, PKIXParameters param, Log log)
throws SarvaraException
{
String errorSubject = "";
String errorDetails = "";
SignBean signReturn = new SignBean();
// set locale for the output
Locale loc = Locale.FRENCH;
// Locale loc = Locale.GERMAN;
// validate signatures
SignedMailValidator validator;
try
{
validator = new SignedMailValidator(msg, param);
...
I dont think the problem comes from the code I wrote because everything's ok oustide axis2 environment. I'm really stuck and I've found nothing about that anywhere. By the way, the MimeMessage constructor takes the Sytem properties in parameter and to be sure that was not the point, I've put exactly the same System properties in both environment (standalone prog and axis2 ws). Every suggestions would be welcome. Thanks you all.

Ok, I've found the problem, and that's really strange... As soon as I remove the geronimo-javamail librarie from the tomcat classpath, all goes well... I really dont know what is the problem with this librarie but the fact is tomcat felt better without it.

Related

CXF STSClient asks for user+password even though there is a SAML token in onBehalfOf

I'm using CXF's STSClient to request a JWT token on behalf of a user so I can call a REST service.
I have a valid SAML token and tried to configure the STSClient like so:
stsClient.setTokenType("urn:ietf:params:oauth:token-type:jwt");
stsClient.setKeyType("http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer");
stsClient.setOnBehalfOf(samlToken.getToken());
stsClient.setEnableAppliesTo(true);
// Not sure about these.
stsClient.setSendRenewing(false);
stsClient.setKeySize(0);
stsClient.setRequiresEntropy(false);
final Map<String, Object> requestContext = Preconditions.checkNotNull(stsClient.getRequestContext());
requestContext.put(SecurityConstants.USERNAME, name); // Without this, I get "No username available"
SecurityToken result = stsClient.requestSecurityToken(appliesTo);
but when the method fails with:
Caused by: org.apache.cxf.interceptor.Fault: No callback handler and no password available
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleBinding(TransportBindingHandler.java:182)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessageInternal(PolicyBasedWSS4JOutInterceptor.java:180)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:110)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:97)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)
at org.apache.cxf.ws.security.trust.AbstractSTSClient.issue(AbstractSTSClient.java:874)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:71)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:65)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:61)
Caused by: org.apache.cxf.ws.policy.PolicyException: No callback handler and no password available
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractCommonBindingHandler.unassertPolicy(AbstractCommonBindingHandler.java:93)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getPassword(AbstractBindingBuilder.java:1042)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.addUsernameToken(AbstractBindingBuilder.java:839)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.addSignedSupportingTokens(TransportBindingHandler.java:115)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleNonEndorsingSupportingTokens(TransportBindingHandler.java:208)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleBinding(TransportBindingHandler.java:167)
... 16 common frames omitted
Since I have a SAML token, I was expecting that the STSClient doesn't need the user name or password anymore.
How can I tell CXF / STSClient to skip the addUsernameToken() method call?
The problem is in the WSDL definition of the service.
Each port in the WSDL is attached to a URL and a binding. The binding has a policy. The policy in this case requests a user name with password. Look for UsernameToken in the WSDL.
What you need is a port that doesn't require this. I'm no expert in this matter but from the examples I've seen, the policy must not have a SignedSupportingTokens element in them, only Wss11 and Trust13 elements.
Without this element, CXF will take a different path in the code and the error will go away.

Apache CXF different ClassLoader Issue

I'm building a SOAP WebService.
In this SOAP Webservice, I want to save the XML request to a file.
To do so, I know I can simply use a chain handler, however, I need other infos that aren't transmitted in the request itself, but rather calculated in the WebService, wich is why I feel like I should retreive the MessageContext in my WebService.
Hopefully, I can use #Resource to get the WebServiceContext and retreive the Message Context. However, I can't seem to be able to cast the MessageContext to the class I want. Here is the code of my endpoint :
import org.apache.cxf.jaxws.context.WrappedMessageContext;
[...]
public MyClass [...] {
[...]
#Resource
WebServiceContext wsContext;
public WSResponse lister(SecurityInfo security, MessageId messageID, RequestBody body) {
if(wsContext.getMessageContext() instanceof WrappedMessageContext) {
//The code never goes in this
}
//However this :
wsContext.getMessageContext().getClass().toString(); //equals this : "org.apache.cxf.jaxws.context.WrappedMessageContext"
//And this is where the problem is
wsContext.getMessageContext().getClass().getClassLoader().toString(); // is : ModuleClassLoader for Module "org.apache.cxf.impl:main" [...]
this.getClass().getClassLoader().toString(); // is : ModuleClassLoader for Module "deployment.my_ws_module.war:main" [...]
}
I didn't even know about CXF 5 days ago, and discovered classloaders yesterday, but I think I kinda understand why is this happening, however, when it comes to solving it, I'm quite clueless...
Worth noting :
The project uses Maven, Spring, CXF and Java 1.8

Error when uploading file with OpenMeetings' importFile REST method

I installed 3.0.3 OpenMeetings to test access via REST interface, everything worked ok for the methods in UserService and RoomService. But, when I try to upload a pdf file by ImportFile method (FileService), OpenMeetings returns an object FileImportError stating that the file is damaged, and that this may have occurred during the file transfer via http.
When I try to import the same file using the flex application of OpenMeetings everything works right. I'm using Ruby to call the method of ImportFile OpenMeeting, and to test whether my application is wrong, I called the method using Firefox and got the same error.
I am using the following method call (sample only, not the real ruby code):
ImportFile (SID externalUserId, externalFileId, externalType, room_id, isOwner, path,
parentFolderId, fileSystemName)
SID = one string with the ID of the session
externalUserId = 'extuser' (string)
externalType = 'exttype' (string)
room_id = 2 (existing room in OpenMeetings)
isOwner = false
path = 'http://10.1.1.25/default.pdf' (The path to the file on an Apache server)
parentFolderId = 0
fileSystemName = 'default.pdf'
Also used Eclipse in remote debug to see what was happening and realized that the problem occurs in the conversion of the received file.
I would appreciate some help to solve the problem.
Thanks,
Fernando

Redirecting in #PostConstruct method resulted in IllegalStateException

According to the answer of BalusC, I used
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
in my #PostConstruct method to stop JSF from rendering the view and redirect users. However, when I try to run the code, I still ran into the java.lang.IllegalStateException exception at the above line.
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:524)
at StudentManagedBean.CourseSummary.init(CourseSummary.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
UPDATE: I added the following line in my #PostConstruct method:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
and what I saw was INIT true. I wonder if the response is supposed to be committed BEFORE the #PostConstruct method is called?
I'd be very grateful if you could give me an advice.
As mentioned in my update, the following line printed INIT true:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
I finally found why the above situation occurred. On my page, before the ManagedBean X, which contains the redirect function, was referenced by UIComponent A, another ManagedBean Y was referenced beforehand by UIComponent B that is placed above UIComponent A in the page structure. As a consequence, the response was partially committed by ManagedBean Y, which makes it impossible for ManagedBean X to send a redirect request.
A redirect will not work here, because even though the response has been completed and finalized, JSF is not smart enough to avoid its typical routine of running through the lifecycle events anyway.
Instead you can try doing a Forward from a RequestDispatcher. A Forward is different from a redirect in the following ways:
Performed internally by the servlet
Browser is apathetic
original url stays intact
Here is some code that displays how this can be done...
RequestDispatcher dispatcher =
((ServletRequest) context.getExternalContext().getRequest())
.getRequestDispatcher("/j_spring_security_logout");
try {
dispatcher.forward((ServletRequest) context.getExternalContext().getRequest(),
(ServletResponse) context.getExternalContext().getResponse());
} catch (ServletException e) {
log.error("ServletException", e);
} catch (IOException e) {
log.error("IOException", e);
}
By doing this you are ending the execution of the FacesServlet prematurely and forwarding it onto a different servlet altogether. I imagine that from this other servlet it might be possible to redirect to the desired location.

RequestFactory service inheritance on the client in GWT 2.4

GWT 2.4 brings service inheritance on the client (issue 6234, issue 6035).
I've been waiting for this future for a long time, as it saves a lot of duplicated code on the client. I've started implementing it, but so for with mixed success.
This is my code:
public interface BaseEntityRequest<T>
{
Request<Void> put(T entity);
Request<List<T>> getAllOrderBy(String propertyName);
Request<List<T>> getRangeAndFilter(int limit,int offset, QueryInfoProxy queryInfo);
}
#Service(value = EgdDao.class, locator = DaoServiceLocator.class)
public interface EgdRequest extends RequestContext, BaseEntityRequest<EgdProxy>
{
Request<Void> exportToExcel(QueryInfoProxy queryInfo, String userName);
}
So far getAllOrderBy and getRangeAndFilter work fine, but put(T entity) does not.
I get the following error in the console:
[ERROR] Unexpected error
java.util.NoSuchElementException
and this gets returned in the receiver onFailure ServerFailure message:
Error 500 INTERNAL_SERVER_ERROR
HTTP ERROR 500
Problem accessing /gwtRequest. Reason:
INTERNAL_SERVER_ERROR
The only cause, that I can see, for the put method not to work, when the others do, is that it uses the generic parameter T. When I move the put method in the EgdRequest interface (using EgdProxy as a parameter instead of T) it starts to work, so I know my server code is fine.
Does anybody have any idea how to implement this correctly?
Thanks!
It's a GWT bug. See http://code.google.com/p/google-web-toolkit/issues/detail?id=6794