-----Ursprüngliche Nachricht-----
Von: André Warnier (tomcat) [mailto:a...@ice-sa.com]
Gesendet: Mittwoch, 28. Oktober 2015 20:42
An: users@tomcat.apache.org
Betreff: Re: AW: AW: Suppress or replace WWW-Authorization header

On 28.10.2015 17:42, Torsten Rieger wrote:
> -----Ursprüngliche Nachricht-----
> Von: Aurélien Terrestris [mailto:aterrest...@gmail.com]
> Gesendet: Mittwoch, 28. Oktober 2015 16:45
> An: Tomcat Users List <users@tomcat.apache.org>
> Betreff: Re: AW: Suppress or replace WWW-Authorization header
>
> You can choose between a pop-up or an HTML FORM
>
> This one looks like this in web.xml :
>
>    <login-config>
>      <auth-method>FORM</auth-method>
>      <realm-name>webapp global realm</realm-name>
>      <form-login-config>
>        <form-login-page>/login.jsp</form-login-page>
>        <form-error-page>/error_login.jsp</form-error-page>
>      </form-login-config>
>    </login-config>
>
>
>
>
> 2015-10-28 16:28 GMT+01:00 Torsten Rieger <torsten.rie...@promatis.de>:
>
>> -----Ursprüngliche Nachricht-----
>> Von: Christopher Schultz [mailto:ch...@christopherschultz.net]
>> Gesendet: Mittwoch, 28. Oktober 2015 15:39
>> An: Tomcat Users List <users@tomcat.apache.org>
>> Betreff: Re: AW: Suppress or replace WWW-Authorization header
>>
>> Torsten,
>>
>> On 10/28/15 8:19 AM, Torsten Rieger wrote:
>>> I have a legacy java-SOAP-client that only supports BASIC
>>> authentication (send the Authorization: Basic... header) and a
>>> AngularJS application that consumes a REST-service (also sending the
>>> Authorization: Basic header).
>>>
>>> The server supports two kinds of deployment: Standalone with an
>>> embedded Jetty-server and as war-file for app-servers (most of them
>>> are tomcat-server). I try to suppress the browser BASIC-login-dialog
>>> for the REST-service-calls from AngularJS.
>>> On Jetty I modify the 401-responses and replace the "WWW-Authenticate"
>>> header by anything else than "BASIC" and that works, now I try to
>>> find a solution for the deployment on tomcat servers.
>>>
>>> Rewrite (unset header in responses) with an apache proxy in front of
>>> the tomcat is unfortunately not a solution I can implement.
>>>
>>> So I'm looking for a solution to remove or modify the headers in 401
>>> responses on application server level.
>>
>> So you just want to disable HTTP BASIC authentication? Why not just
>> remove the <auth-method> from web.xml and disable authentication
>> entirely?
>>
>> Are you saying that when you connect using a REST client, the client
>> shows a login dialog in a web browser? That sounds ... weird. The
>> REST client should see the WWW-Authenticate header and either (a)
>> fail or
>> (b) re-try with credentials you have provided to it.
>>
>> -chris
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
>> For additional commands, e-mail: users-h...@tomcat.apache.org
>>
>> No, container BASIC authentication should be enabled, the container
>> should handle the authentication, but the browser should not show his
>> ugly default login dialog when I request resources from the
>> REST-service with wrong credentials.
>> When the REST-client (web-application in the browser) receives a
>> failed login with a WWW-Authenticate header, the default dialog of
>> the browser will be shown... that’s what I want to suppress.
>>
>> When I remove the (a) <login-config> or (b) <auth-method>  sending
>> requests with credentials will not work anymore (a: 403 forbidden; b:
>> deployment fails). But that's not a solution because the rest-service
>> should be still protected and I need to authenticate via "Authentication:
>> Basic ....."
>> header send credentials, but I don't want to show the ugly
>> browser-dialog to the users.
>>
>> Using a AngularJS Client with REST-services based on tomcat should be
>> a common use-case, it could not be that I'm the first one who wants a
>> custom login-screen. :-/
>>
>> -torsten
>>
>
>
> The Problem is then, that login via "Authorization: BASIC xyz==" will
> not work anymore... the legacy client is not able to handle FORM based
> login :-/
>

Torsten, let me try again another way :

1)
 >> Using a AngularJS Client with REST-services based on tomcat should be
 >> a common use-case, it could not be that I'm the first one who wants a  >>
custom login-screen. :-/

No, you probably are not.  But *this has nothing to do with Tomcat per se*.
Any other webserver, in the same circumstances, would send a 401 back, with
a request for HTTP Basic authentication.
If, at the server level, you configure that for this application, you want
HTTP Basic authentication, then that is what you will get.  It is not a
choice of the server, it is something *imposed* by the HTTP protocol.

If you want something else to happen, but still have the client be
authenticated for that application, then you have to change the
authentication method required, at the server level.  No way around it.

2) If the browser receives a 401 response header which indicates that the
requested authentication method should be HTTP Basic, then it will popup its
bultin HTTP Basic authentication popup dialog.  There is no easy way around
this either, because this behaviour is built-in into the code of all major
browsers.
(Also because the HTTP protocol says that this is what the browser should
do).
If you want this to be different, then you have to find a way to modify the
browser-side logic, so that it does not do that.  Doing this is possible,
but not easy (see some of the other responses), and if not done correctly,
it will be buggy and/or introduce security issues.

3) all the responses which I have seen so far on this thread, are
technically correct considering the information which you have provided as
to what you would like, and what your client-side application can/cannot do.
But maybe here, we were all seeing the tree that you put in front of us, and
for that reason not seeing the forest behind it.

4) Setting the server-side to do authentication in a different way than HTTP
Basic, does not necessarily mean that your application cannot, overall, be
authenticated.

The REST application on the server, presumably, does not care *how* the user
is authenticated.  It just wants an authenticated user, no matter how that
happens.
It gets the user-id from Tomcat (via request.getUser() or similar), *after*
Tomcat has taken care of the authentication.  The way in which Tomcat
obtains this user-id is not the concern of the application. (At least, that
is what a well-behaved application would do).

5) So let's do the authentication in another way, so that the client never
even sees a 401 response from the server, and thus never pops up this dialog
that you do not want to see.

At the server level, use the form-based authentication, like another poster
here already suggested.
What would happen then is as follows :

a) the browser sends a first request to the REST app, un-authenticated.
b) the server sees that this is not authenticated, and sends back to the
browser, a login form.  Note that this is just a html page, that has nothing
to do with the client-side application. (Note : you create this login form,
and save it on the server.
You just need to tell the server (in the web.xml of the REST application)
where this login form is.)
c) the human client fills-in the login form, and his browser posts it back
to the server.
This goes to another URL on the server (e.g. "/login"), that is *not* the
REST application.
d) on the server, the login application at "/login" authenticates the user
and creates a session, where this authenticated user-id is stored. It also
sets the authenticated user-id in the Tomcat request structure, for later
usage.
The login application also prepares a "session-id" cookie, to be sent back
to the browser (later), which points to this saved session on the server.
e) The login application now redirects the browser, to the original URL that
it was requesting, before all this authentication stuff took place.
That is the REST application.
f) now the REST application gets called, and it can retrieve the user-id
from Tomcat, as promised.  So it does its work, and sends back the response
to the browser.
(Notice that there has never been a 401 response so far)
g) the browser gets the 1st response from the REST application. It also
gets, at the same time, the session-id cookie that was added by the
authentication part.
h) if the browser now sends a second request to the REST application, this
session-id cookie will be re-sent to the server also.
i) the server now gets the new request, and the cookie.  The server uses the
cookie to retrieve the saved session, including the user-id in it.  The
server uses this to set the internal Tomcat user-id, and calls the REST
application again.
j) the REST application starts working, and retrieves the user-id from
Tomcat. So it is happy, and sends back the next response.
Tomcat takes care that with this next response, the session-id cookie header
is sent again to the browser.
k) the browser sends another request to the server. Go to (h) above.

Notice : still no 401 Basic response header anywhere, so no browser-side
Basic auth popup.
Notice also : the client-side application is never really involved in the
authentication.
So whatever it supports or not, is not relevant here.

Note that all the above supposes that the client application on the browser
side, does not need to know that it is authenticated.  But that is normally
the case for client-side applications.

Last note : in the a-k explanation above, I have taken some liberties with
the intimate details of how things happen on the server. I hope that the
purists will forgive this bit of poetic and tutorial license. Hopefully, it
should allow Torsten to get going along the right track, instead of pursuing
mirages.



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


FORM-based is not possible because of the legacy client, which only supports
BASIC-auth.
You are right, it's a problem all servers... imho it's a problem of that old
standard from the 90th, because there was no real logic on client side:
Let's have a look at the informations:
1) 401 -> Unauthorized
2) WWW-Authenticate: BASIC realm="xyz" --> Method

But that should be only interpreted as: "please send your username/password
as 'BASIC 4324CAF323=='" and NOT as "show an ugly dialog". There is no
chance to use auth with 'BASIC ...' but with an custom dialog.

That the clients can send their credentials in a BASIC compatible style is a
hard requirement. Because just one auth-method is allows for an application
in an web.xml and that must be BASIC because of the legacy client. ... but
that client doesn't matter if there is a BASIC challenge send by the server.
;-)

All solutions on application level (client or server side) will not work,
because 401-response and the processing which is leading on the client side
are handled by container and browser without a chance to modify anything by
custom code. The only way is to remove security constraints and to handle it
in my own code but without authentication capabilities from container level
except I use request.login (Servlet 3.0 API) which delegates up to
container-level from application code.
BUT I use the equinoxbridge.jar to forward all requests from the outer
container to an inner OSGi-based cxf server, and it seems that this bridge
makes everything more complicated... that .login() didn't work for me, I
think doesn't reach the outer container. :-/

If I had an normal jersey application, I could use a ContainerResponseFilter
to modify 401-errors, but that doesn't work with that equinoxbrigde because
it's a normal servlet without support for such filters... and the inner
application after that bridge is not reached if credentials are wrong.

I still thought "removing that BASIC in the WWW-authenticate header will be
a best fitting solution" ... that seems to be best practice
(https://github.com/gbif/registry/blob/master/registry-ws/src/main/java/org/gbif/registry/ws/filter/AuthResponseCodeOverwriteFilter.java)
 and in the standard: challenged auth-method in the response must not be the
same as send before by the client.

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

Reply via email to