To get back to the underlying issue :

Auth Gábor wrote:

So... this is the real chaos... :)

Yes.


By the way, my users are not use HTML browsers, they are using JAX-WS in their client program, and the JAX-WS sends authentication data in UTF-8 (like Opera), because the default encoding is UTF-8 in the client JVM (and the server too).


Basically, I would tend to say that if the server knows who the clients are and vice-versa, you should be free to use any encoding you want, with the limitation that what is exchanged on the wire conforms to HTTP (because there may be proxies on the way which are not so tolerant).

What the client is sending is already (in a way) conformant to HTTP, because it is base64 encoded and so, on the surface, it does not contain non-ascii characters. And (I presume) you cannot change the code of the client, so it will continue to send these "invalid" headers with a UTF-8 value, base64-encoded.

But the problem is that the standard Tomcat code which decodes the Basic Authorization header does not work in the way you want, for these illegal headers. And this code should preferably not be changed in a way which breaks the conformance with standard HTTP. Because if you do that, then your Tomcat becomes useless for anything else than your special client.

An additional complication is that, if you want to use the embedded "container-managed" Tomcat authentication mechanisms, then you have to do something very early in the cycle, because that authentication takes place even before any servlet filter is invoked.

Up to Tomcat 5.5, you would have to do this in a Valve then, which has the inconvenient that it is Tomcat-specific. (I think Tomcat 6 may give other options, maybe not Tomcat-specific.)

Or, you drop the container-managed security, and you use something like the SecurityFilter (http://securityfilter.sourceforge.net/), but read the homepage carefully first.

So, to be pragmatic, I would tend to go in the following direction :
- create a Valve which
- checks the User-Agent. If it does not match your special client, do nothing. If it matches, then
- get the Authorization header. If there is none, do nothing
- else, decode its value properly into a Unicode string
- re-encode this string in a way that fits with standard HTTP. For example, replace each character by a string like {xxxx}, where xxxx is the hex value of the Unicode codepoint of the character.
(That is always valid us-ascii, but check the maximum length).
- re-encode the result using base64
- replace the Authorization header value with this new string
- in your back-end authentication mechanism (I will suppose it is a database of userids/passwords), encode the userids/passwords the same way, and make this an alternate key

The embedded Tomcat authentication will then decode the new base64 string, split it into userid:password, and use them to verify the credentials, which will match.

If you do not like a Valve, then use a front-end server like Apache, and do the transformation of the header there, before the request is passed to Tomcat. Alternatively then, you could also do the user authentication at the Apache level, and just pass the user-id to Tomcat. (being an Apache/mod_perl guy myself, I find this last option much easier, but YMMV).

And all that for a few Ö's and Á's and ß's....













Another option is to use a front-end Apache httpd server, which would modify the requests as follows :

(I presume that you have a way to identify requests coming from this particular client)(User-Agent header e.g.).

Create a filter at the Apache level, which detects your special client.
If it detects it, then it adds an additional header to the request

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to