问题
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?
回答1:
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
回答2:
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
extendingRuntimeException
. 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 catchPropagatedHttpException
and pass it on as a proper HTTP error.
- Override writeError to check if the error is a
- Extend
XmlRpcServlet
:- Set a custom
AuthenticationHandler
which throwsPropagatedHttpException
for specific HTTP error codes. - Override
newXmlRpcServer
to return the customXmlRpcServletServer.
- Set a custom
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.
来源:https://stackoverflow.com/questions/8891554/xml-rpc-authentication-http-vs-xmlrpcnotauthorizedexception