1

I could not find an exact answer to my question (either google or here), so my apologies if this is a repeat that I missed:

I am writing a XML-RPC server using Apache's XML-RPC libraries (which I'm regretting a bit) in Java that needs to conform to a given specification. With authentication, the server generates an org.apache.xmlrpc.common.XmlRpcNotAuthorizedException. This is not the behaviour that is required. I would like to return an HTTP error 401 (not authenticated) and 403 (forbidden) instead. However, Apache keeps on throwing these exceptions and I cannot find a way around it.

For example response received after sending correct username/password:

HTTP/1.1 200 OK
Content-Length:362
Content-Type:text/xml
Server:Jetty(7.x.y-SNAPSHOT)

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
    ...correct response information here 
</methodResponse>

...and wrong username and password:

HTTP/1.1 200 OK
Content-Length:252
Content-Type:text/xml
Server:Jetty(7.x.y-SNAPSHOT)

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
   ...xmlrpc exception here 
<methodResponse>

I don't want "HTTP/1.1 200 OK", I want "HTTP/1.1 401 Unauthorized"

I was considering inheriting Apache's ReflectiveXmlRpcHandler (or something similar) and trying to intercept the exception, but I was wondering if someone else have found a better idea to this problem.

Any ideas?

2 Answers 2

2
+150

That seems to be difficult. As stated in the XML-RPC Specification

Response format

Unless there's a lower-level error, always return 200 OK.

Bad Authentication Credentials is not a low-level error, it's just a particular use case. But you can enable Exceptions on the client side (be aware of security issues) to handle this particular case

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you... I came to the same conclusion during the last few days. What do you think about handling this on the HTTP server (Jetty in my case)? Would you handle the authentication there before it gets passed to the XML-RPC library? i.e. fail-fast?
What king of authentication do you provide ? Basic via HTTP ?
Yes, basic HTTP authentication.
Grooveek? ...any comments? Bounty about to expire, I'd like to award it if you can provide some insight.
I've taken some time to jump into the sources of the library but cannot see any method or class to hook at, since pretty all of them throws XMLRpcException. If you don't use the default webserver, solution would be to implement a BasicHttpAuthenticationFilter which would delegate request treatment only if the authentication is successful. You could then return a 401/403. I can't really help you much more than that, sorry.
|
1

I would post code but it touches a few too many places and by the time I had it here, it was an essay...

What I did:

  • Created PropagatedHttpException extending RuntimeException. It just has one field, code, which is the HTTP error code.
  • Extend XmlRpcServletServer:
    • Override writeError to check if the error is a PropagatedHttpException and if it is, throw it back out immediately.
    • Override execute(HttpServletRequest, HttpServletResponse) to catch PropagatedHttpException and pass it on as a proper HTTP error.
  • Extend XmlRpcServlet:
    • Set a custom AuthenticationHandler which throws PropagatedHttpException for specific HTTP error codes.
    • Override newXmlRpcServer to return the custom XmlRpcServletServer.

We already had a custom authentication handler when we started to figure out how this would work but in your case maybe it isn't needed and the writeError code could be adjusted to check for XmlRpcNotAuthorizedException. Actually I had no idea this exception existed until today...

The problem you'll have now is that from the client side, Apache XML-RPC doesn't check the error code it gets back and then tries to parse the XML response irrespective of the result.

Grooveek's answer is extremely disheartening to us as we want authentication to be hooked into the JRE's built-in authentication so that things like NTLM can work, but if it's going to return an HTTP 200 then it is impossible for this to ever work without breaking the spec.

4 Comments

What I essentially did was to abandon all the authentication that occurs in Apache. I use Jetty as the webserver and intercepted the call before it goes the XML-RPC part. This works as a charm and actually resulted in a faster response as well (see the accepted answer). Thank you for sharing your experience as well! (+1)
Yeah, in our case though, different XML-RPC objects have different access levels. So unfortunately for the time being we're dead in the water...
@Trejkaz Aren't credentials mainly for ID, and the application then determins authorization? Authozation should be out of band (locally stored or remote), not in the data transaction channel.
@Dennis the application is determining authorisation. The problem was that when denial of access happened, the HTTP response code was misleadingly suggesting that the request succeeded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.