bbotz
bbotz

Reputation: 63

Mule http response builder 401 status

I'd like to return a 401 HTTP_response after a failed authentication. I am trying to do this through the use of a http:response-builder component with the configuration below. I don't care about anything previous within the flow, once it reaches this point all it needs to do is this.

<flow name="main" doc:name="main">
<http:inbound-endpoint exchange-pattern="request-response"
    address="http://localhost:8081/example" doc:name="HTTP" />
<byte-array-to-string-transformer
    doc:name="Byte Array to String" />
<cxf:proxy-service namespace=""
        service="" payload="envelope"
        wsdlLocation=""
        enableMuleSoapHeaders="false" doc:name="ProxyService"/>
<cxf:proxy-client payload="envelope" enableMuleSoapHeaders="true" doc:name="ProxyClient" />
<http:outbound-endpoint exchange-pattern="request-response"
        address=""
        doc:name="request" />
<byte-array-to-string-transformer
    doc:name="Byte Array to String" />
<logger message="The payload after the request is:#[payload]"
    level="INFO" doc:name="Logger" />
<choice doc:name="Choice">
...
<otherwise>
    <processor-chain>
        <logger message="Failed authentication is:#[payload]" level="INFO"
            doc:name="Logger" />
        <http:response-builder status="401"
            doc:name="HTTP Response Builder">
            <set-payload value="Authentication Failed" />
        </http:response-builder>
    </processor-chain>
</otherwise>

The error that I'm receiving through soapUI

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Server</faultcode>
         <faultstring>Could not find a transformer to transform "SimpleDataType{type=org.mule.transport.http.HttpResponse, mimeType='text/xml'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}". (org.mule.api.transformer.TransformerException). Message payload is of type: PostMethod</faultstring>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>.

To me this says my current message is of text/xml, and it's trying to return a unknown type. I've tried setting the content type of the builder to text/xml with the same results

Edit: The current status is HTTP/1.1 500 Internal Server Error

Many thanks for your time reading, and any replies.

Upvotes: 1

Views: 6152

Answers (1)

David Dossot
David Dossot

Reputation: 33413

You can't use the http:response-builder where you use it because its output will not be directly dealt with by the HTTP inbound endpoint but by the cxf:proxy-service. When the response is coming downstream the flow towards the inbound endpoint it hits the cxf:proxy-service which takes care of preparing the SOAP response: it can only deal with a message that has a SOAP payload and will control strictly the status code, overriding any attempt to set it up elsewhere in the flow. Moreover, in your case, you're building a non-SOAP response which will make the cxf:proxy-service even unhappier when it'll deal with the response.

So the trick is to separate the detection of the failed login from the building of the HTTP response, and locate the HTTP response building in the response phase of the flow. This gives:

<flow name="main" doc:name="main">
    <http:inbound-endpoint exchange-pattern="request-response"
        address="http://localhost:8081/example" doc:name="HTTP" />
    <response>
        <expression-filter expression="#[flowVars.authenticationFailed]" />
        <http:response-builder status="401"
            doc:name="HTTP Response Builder">
            <set-payload value="Authentication Failed" />
        </http:response-builder>
    </response>
    <byte-array-to-string-transformer
        doc:name="Byte Array to String" />
    <cxf:proxy-service namespace=""
            service="" payload="envelope"
            wsdlLocation=""
            enableMuleSoapHeaders="false" doc:name="ProxyService"/>
    <cxf:proxy-client payload="envelope" enableMuleSoapHeaders="true" doc:name="ProxyClient" />
    <http:outbound-endpoint exchange-pattern="request-response"
            address=""
            doc:name="request" />
    <byte-array-to-string-transformer
        doc:name="Byte Array to String" />
    <logger message="The payload after the request is:#[payload]"
        level="INFO" doc:name="Logger" />
    <set-variable variableName="authenticationFailed" value="false" />
    <choice doc:name="Choice">
    ...
    <otherwise>
        <processor-chain>
            <logger message="Failed authentication is:#[payload]" level="INFO"
                doc:name="Logger" />
            <set-variable variableName="authenticationFailed" value="true" />
        </processor-chain>
    </otherwise>

Notice the use of a flow variable (named authenticationFailed) to control the response.

Upvotes: 1

Related Questions