Help get this topic noticed by sharing it on Twitter, Facebook, or email.

HTTP Authentication with JMS Request Response

I've created a simple flow that exposes an HTTP endpoint linked to a REST service. The REST service returns a String which is then placed onto a JMS queue using the request-response pattern. The idea is that the String placed on the queue will be consumed by some consumer and a reponse will created using the Reply-To address. So basically this is implimenting synchronous JMS.

The flow works as expected, except when the HTTP endpoint is secured using Basic Authentication. In this case the response is:


java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1


and no message is placed on the queue. Removing Basic Authentication results in no exception being thrown. Also, removing the JMS outbound endpoint results in the String being echoed back which leads me to believe the problem is with the JMS endpoint. I suspect that the problem is with the response from the JMS endpoint because setting component in the flow to one-way negates the problem. I think the issue might be that the endpoint is sending some response to the HTTP endpoint without authentication credentials and it fails because of it, but I'm unsure how to deal with this.

Below is the flow that I created:


<mule
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:core="http://www.mulesoft.org/schema/mule/core"
version="CE-3.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:ss="http://www.springframework.org/schema/security" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/3.1/mule-spring-security.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd ">
<jms:activemq-connector name="Active_MQ" specification="1.1" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
<mule-ss:security-manager>
<mule-ss:delegate-security-provider name="memory-provider" delegate-ref="authenticationManager"/>
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider>
<ss:user-service id="userService">
<ss:user name="username" password="password" authorities="ROLE_ADMIN"/>
</ss:user-service>
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<flow name="RESTAPISync" doc:name="RESTAPISync">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" >
<mule-ss:http-security-filter realm="realm"/>
</http:inbound-endpoint>
<jersey:resources doc:name="REST">
<component class="SFREST"/>
</jersey:resources>
<jms:outbound-endpoint exchange-pattern="request-response" queue="tmp" connector-ref="Active_MQ" doc:name="JMS"/>
</flow>
</mule>


The SFREST.java component:


import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/pops")
public class SFREST{

@GET
public String getPOPs() throws Exception{
return "hello";
}

}


And the exception:


ERROR 2012-11-04 21:40:57,485 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Authentication Attempt Failed. Message payload is of type: String
Code : MULE_ERROR-54999
--------------------------------------------------------------------------------
Exception stack is:
1. Bad credentials (org.springframework.security.authentication.BadCredentialsException)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider:137 (null)
2. Authentication Attempt Failed. Message payload is of type: String (org.mule.api.security.UnauthorisedException)
org.mule.security.MuleSecurityManager:96 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/security/UnauthorisedException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:137)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.mule.module.spring.security.SpringProviderAdapter.authenticate(SpringProviderAdapter.java:70)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

get!
ERROR 2012-11-04 21:41:04,522 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1
Code : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. com.sun.jersey.spi.container.ContainerResponse (java.io.NotSerializableException)
java.io.ObjectOutputStream:1164 (null)
2. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException)
org.apache.commons.lang.SerializationUtils:111 (null)
3. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1 (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:35 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.commons.collections.map.AbstractHashedMap.doWriteObject(AbstractHashedMap.java:1182)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
1 person has
this question
+1
Reply
  • Hi Allan Chang,

    I have simulated your problem by giving wrong password. Please try the below one..

    http:\\localhost:8082\pops

    Enter username as username
    Enter password as password

    Note : if you want to try next time - change port otherwise needs to clear browser histories...


    <mule-ss:security-manager>
    <mule-ss:delegate-security-provider
    name="memory-provider" delegate-ref="authenticationManager" />
    </mule-ss:security-manager>
    <spring:beans>
    <ss:authentication-manager alias="authenticationManager">
    <ss:authentication-provider>
    <ss:user-service id="userService">
    <ss:user name="username" password="password" authorities="ROLE_ADMIN" />
    </ss:user-service>
    </ss:authentication-provider>
    </ss:authentication-manager>
    </spring:beans>

    <flow name="testFlow1" doc:name="testFlow1">
    <http:inbound-endpoint exchange-pattern="request-response"
    host="localhost" port="8082" doc:name="HTTP">
    <mule-ss:http-security-filter realm="realm" />
    </http:inbound-endpoint>
    <jersey:resources doc:name="REST">
    <component class="org.example.SFREST" />
    </jersey:resources>
    </flow>


    if i give wrong password , i will get as (MULE_ERROR-54999)

    ERROR 2012-11-08 16:54:48,879 [[hello_world].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
    ********************************************************************************
    Message : Authentication Attempt Failed. Message payload is of type: String
    Code : MULE_ERROR-54999
    --------------------------------------------------------------------------------
    Exception stack is:
    1. Bad credentials (org.springframework.security.authentication.BadCredentialsException)
    org.springframework.security.authentication.dao.DaoAuthenticationProvider:67 (null)
    2. Authentication Attempt Failed. Message payload is of type: String (org.mule.api.security.UnauthorisedException)
    org.mule.security.MuleSecurityManager:96 (http://www.mulesoft.org/docs/site/cur...)
    --------------------------------------------------------------------------------
    Root Exception stack trace:
    org.springframework.security.authentication.BadCredentialsException: Bad credentials
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:67)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:139)
    at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:130)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • This reply was removed on 2012-11-08.
    see the change log
  • Hi Subramanian,

    Thanks for the reply. In that situation I am able to get the correct response from the HTTP endpoint, however if I include


    <jms:outbound-endpoint exchange-pattern="request-response" queue="tmp" connector-ref="Active_MQ" doc:name="JMS"/>


    in the flow so that it becomes:


    <flow name="testFlow1" doc:name="testFlow1">
    <http:inbound-endpoint exchange-pattern="request-response"
    host="localhost" port="8082" doc:name="HTTP">
    <mule-ss:http-security-filter realm="realm" />
    </http:inbound-endpoint>
    <jersey:resources doc:name="REST">
    <component class="org.example.SFREST" />
    </jersey:resources>
    <jms:outbound-endpoint exchange-pattern="request-response" queue="tmp" connector-ref="Active_MQ" doc:name="JMS"/>
    </flow>


    then it will fail with the error mentioned in my post above even if I input the correct password.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • You can't simply call another flow or message processor after a jersey resource wihtout transforming it from a MuleResponseWriter first - http://www.mulesoft.org/documentation...

    From the docs:

    If you want to transform or send the request from your jersey component to next resource/flow then you need to use

    ContainerResponse cr = (ContainerResponse) message.getInvocationProperty("jersey_response");
    String messageString = (String) cr.getResponse().getEntity();
    message.setPayload(messageString);


    This will convert org.mule.module.jersey.MuleResponseWriter$1 type to String, which you can forward to your next resource.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Hi Allan Chang,

    I hope, i found the issue. Please remove jersey_response property before sending to JMS because jersey_response unable to Serializable


    <jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61617" validateConnections="true" doc:name="Active MQ"/>
    <mule-ss:security-manager>
    <mule-ss:delegate-security-provider name="memory-provider" delegate-ref="authenticationManager"/>
    </mule-ss:security-manager>
    <spring:beans>
    <ss:authentication-manager alias="authenticationManager">
    <ss:authentication-provider>
    <ss:user-service id="userService">
    <ss:user name="username" password="password" authorities="ROLE_ADMIN"/>
    </ss:user-service>
    </ss:authentication-provider>
    </ss:authentication-manager>
    </spring:beans>
    <flow name="testFlow1" doc:name="testFlow1">
    <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8083" doc:name="HTTP">
    <mule-ss:http-security-filter realm="realm"/>
    </http:inbound-endpoint>
    <jersey:resources doc:name="REST">
    <component class="org.example.MyRest"/>
    </jersey:resources>
    <logger level="INFO" doc:name="Logger"/>
    <message-properties-transformer scope="invocation">
    <delete-message-property key="jersey_response" />
    </message-properties-transformer>

    <jms:outbound-endpoint exchange-pattern="request-response" queue="MyQueue" connector-ref="Active_MQ" doc:name="JMS"/>
    </flow>



    package com.subu.mule;

    import org.mule.api.MuleMessage;
    import org.mule.api.transformer.TransformerException;
    import org.mule.api.transport.PropertyScope;
    import org.mule.transformer.AbstractMessageTransformer;

    public class ResponseTransformer extends AbstractMessageTransformer {

    @Override
    public Object transformMessage(final MuleMessage arg0, String arg1)
    throws TransformerException {
    try {
    System.out.println(arg0.getPayloadAsString());
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    try {
    return arg0.getPayloadAsString();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return "";
    }

    }
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Unfortunalety no luck.

    I changed my flow to incorporate the solutions above to:


    <jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
    <mule-ss:security-manager>
    <mule-ss:delegate-security-provider name="memory-provider" delegate-ref="authenticationManager"/>
    </mule-ss:security-manager>
    <spring:beans>
    <ss:authentication-manager alias="authenticationManager">
    <ss:authentication-provider>
    <ss:user-service id="userService">
    <ss:user name="username" password="password" authorities="ROLE_ADMIN"/>
    </ss:user-service>
    </ss:authentication-provider>
    </ss:authentication-manager>
    </spring:beans>
    <flow name="testFlow1" doc:name="testFlow1">
    <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8083" doc:name="HTTP">
    <mule-ss:http-security-filter realm="realm"/>
    </http:inbound-endpoint>
    <jersey:resources doc:name="REST">
    <component class="SFREST"/>
    </jersey:resources>
    <custom-transformer class="ResponseTransformer" doc:name="Java"/>
    <logger level="INFO" doc:name="Logger"/>
    <message-properties-transformer doc:name="Message Properties">
    <delete-message-property key="jersey_response" />
    </message-properties-transformer>
    <logger level="INFO" doc:name="Logger"/>
    <jms:outbound-endpoint exchange-pattern="request-response" queue="MyQueue" connector-ref="Active_MQ" doc:name="JMS"/>
    </flow>


    where ReponseTransformer implements Subramanian's class. This now results in the error message


    java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: String


    The strange thing is that deleting the message property does not seem to work in my case. I placed a logger before and after the delete and the messages that are logged are

    before:


    INFO 2012-11-08 22:09:19,156 [[jmstest].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor:
    org.mule.DefaultMuleMessage
    {
    id=2db38980-29e0-11e2-8ae7-1fe1b6c8a00f
    payload=java.lang.String
    correlationId=<not set>
    correlationGroup=-1
    correlationSeq=-1
    encoding=UTF-8
    exceptionPayload=<not set>

    Message properties:
    INVOCATION scoped properties:
    jersey_response=com.sun.jersey.spi.container.ContainerResponse@b1ea3fc
    INBOUND scoped properties:
    Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding=gzip, deflate
    Accept-Language=en-us,en;q=0.5
    Authorization=Basic dXNlcm5hbWU6cGFzc3dvcmQ=
    Connection=true
    Host=localhost:8083
    Keep-Alive=true
    MULE_ORIGINATING_ENDPOINT=endpoint.http.localhost.8083
    MULE_REMOTE_CLIENT_ADDRESS=/127.0.0.1:47368
    User-Agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0
    http.context.path=/
    http.context.uri=http://localhost:8083
    http.headers={Accept-Language=en-us,en;q=0.5, Authorization=Basic dXNlcm5hbWU6cGFzc3dvcmQ=, Host=localhost:8083, Accept-Encoding=gzip, deflate, User-Agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0, Keep-Alive=true, Connection=true, Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8}
    http.method=GET
    http.query.params={}
    http.query.string=
    http.relative.path=pops
    http.request=/pops
    http.request.path=/pops
    http.version=HTTP/1.1
    OUTBOUND scoped properties:
    Content-Type=text/html
    MULE_ENCODING=UTF-8
    http.status=200
    SESSION scoped properties:
    }


    after


    INFO 2012-11-08 22:09:19,157 [[jmstest].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor:
    org.mule.DefaultMuleMessage
    {
    id=2db38980-29e0-11e2-8ae7-1fe1b6c8a00f
    payload=java.lang.String
    correlationId=<not set>
    correlationGroup=-1
    correlationSeq=-1
    encoding=UTF-8
    exceptionPayload=<not set>

    Message properties:
    INVOCATION scoped properties:
    jersey_response=com.sun.jersey.spi.container.ContainerResponse@b1ea3fc
    INBOUND scoped properties:
    Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding=gzip, deflate
    Accept-Language=en-us,en;q=0.5
    Authorization=Basic dXNlcm5hbWU6cGFzc3dvcmQ=
    Connection=true
    Host=localhost:8083
    Keep-Alive=true
    MULE_ORIGINATING_ENDPOINT=endpoint.http.localhost.8083
    MULE_REMOTE_CLIENT_ADDRESS=/127.0.0.1:47368
    User-Agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0
    http.context.path=/
    http.context.uri=http://localhost:8083
    http.headers={Accept-Language=en-us,en;q=0.5, Authorization=Basic dXNlcm5hbWU6cGFzc3dvcmQ=, Host=localhost:8083, Accept-Encoding=gzip, deflate, User-Agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0, Keep-Alive=true, Connection=true, Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8}
    http.method=GET
    http.query.params={}
    http.query.string=
    http.relative.path=pops
    http.request=/pops
    http.request.path=/pops
    http.version=HTTP/1.1
    OUTBOUND scoped properties:
    Content-Type=text/html
    MULE_ENCODING=UTF-8
    http.status=200
    SESSION scoped properties:
    }


    as you can see the payload is a String. The weird thing is that the jersey_response property is not being removed as it can be seen in the log message after it is meant to be removed. Could this be a version issue? I've running the Community Edition 3.3.0. Thanks for the help so far.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • 1
    Hi Allan Chang, ,

    you have not include the scope attribute in the message-properties-transformer. Please refer below (or refer my previous one) ..(scope="invocation") . That is reason it is deleted and could not find in the default scope....


    .....
    <message-properties-transformer scope="invocation">
    .....



    I hope, it will work now after include scope as invocation :-)
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Thanks Subramanian! I added the scope and it works as expected. Thanks for all your help.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly sad, anxious, confused, frustrated indifferent, undecided, unconcerned happy, confident, thankful, excited