You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by Magnus Johansson <kk...@gmail.com> on 2009/07/02 22:30:33 UTC

Why does SlingAuthenticator redirect to LoginServlet?

Hi
I'm very new to sling so please forgive me if this is a stupid question.

I'm trying to implement form based authentication as an alternative to http
basic Authentication.
As far as I understand SlingAuthenticator will redirect to
/system/sling/login if the user is not
yet logged in and anonymous access is not enabled. The LoginServlet will
then call login on the
AuthenticationHandler (via SlingAuthenticator). This causes some problems
for me where I
want a successful authenticaton to redirect the user back to the original
page he tried to access.

When the login method on my AuthenticationHandler is called there is no way
to get the original uri,
as the user has just been redirected to /system/sling/login

My question is thus, why does SlingAuthenticator redirect to the
LoginServlet instead of
just calling login on the appropriate AuthenticationHandler (this is what
LoginServlet does anyway).
If this was the case I could easily temporarily store the original uri in a
cookie, session or similar to
be able to redirect the user back after a successful authentication.

Another question related to implementing alternate authentication methods.
Is it possible to register
servlets (under /system/sling for instance) that does not require the user
to be authenticated even
if anonymous access on SlingAuthenticator is disabled.


Regards
Magnus Johansson

Re: Why does SlingAuthenticator redirect to LoginServlet?

Posted by Magnus Johansson <kk...@gmail.com>.
Thanks

Regards
Magnus Johanson



On 7/4/09, Felix Meschberger <fm...@gmail.com> wrote:
> Hi Magnus,
>
> Magnus Johansson schrieb:
>> Hi
>>
>> Thanks for your answer... it all makes sense except for one small detail
>>
>> If I try to follow the code this is my understanding:
>>
>>  1. SlingAuthenticator calls my AuthenticationHandler.authenticate
>>  2. AuthenticationHandler.authenticate return null as no user is currently
>> logged in
>>  3. SlingAuthenticator will now call
>> SlingAuthenticator.getAnonymousSession
>>  4. SlingAuthenticator.getAnonymousSession will redirect to LoginServlet
>
> Oops, this is probably not correct and getAnonymousSession should
> probably call login directly...
>
>>  5. LoginServlet will call AuthenticationHandler.login (via
>> SlingAuthenticator)
>>
>> In step 5 my AuthenticationHandler can not get the original request uri
>> that
>> was requested
>> by the user at 1 because of the redirect in step 4.
>
> Correct ...
>
>>
>> One solution/hack in my AuthenticationHandler would be in step 2 to return
>> incorrect
>> credentials instead of returning null. This would force SlingAuthenticator
>> to call handleLoginFailure and
>> thus login on my AuthenticationHandler. However, this would mean that I
>> "loose" the built-in
>> support for anonymous users.
>>
>> The other solution would be for step 4 to actually call
>> AuthenticationHandler.login directly (without
>> a redirect). This might of course have some unwanted side-effects that I
>> haven't thought of.
>
> I would assume, that this is probably an oversight of mine when I
> refactored the login mechanism adding the AuthenticaitonService.login
> method.
>
> I created SLING-1032 [1] to track this and fix it by calling login if
> anonymous access is not allowed. And fixed in the engine bundle in Rev.
> 791120.
>
> IIRC we keep the LoginServlet for backwards compatibility and for an
> easy entry point into generic system login. As such the LoginServlet
> should be accessed from the outside and not from within.
>
> Regards
> Felix
>
> [1] https://issues.apache.org/jira/browse/SLING-1032
>

Re: Why does SlingAuthenticator redirect to LoginServlet?

Posted by Felix Meschberger <fm...@gmail.com>.
Hi Magnus,

Magnus Johansson schrieb:
> Hi
> 
> Thanks for your answer... it all makes sense except for one small detail
> 
> If I try to follow the code this is my understanding:
> 
>  1. SlingAuthenticator calls my AuthenticationHandler.authenticate
>  2. AuthenticationHandler.authenticate return null as no user is currently
> logged in
>  3. SlingAuthenticator will now call SlingAuthenticator.getAnonymousSession
>  4. SlingAuthenticator.getAnonymousSession will redirect to LoginServlet

Oops, this is probably not correct and getAnonymousSession should
probably call login directly...

>  5. LoginServlet will call AuthenticationHandler.login (via
> SlingAuthenticator)
> 
> In step 5 my AuthenticationHandler can not get the original request uri that
> was requested
> by the user at 1 because of the redirect in step 4.

Correct ...

> 
> One solution/hack in my AuthenticationHandler would be in step 2 to return
> incorrect
> credentials instead of returning null. This would force SlingAuthenticator
> to call handleLoginFailure and
> thus login on my AuthenticationHandler. However, this would mean that I
> "loose" the built-in
> support for anonymous users.
> 
> The other solution would be for step 4 to actually call
> AuthenticationHandler.login directly (without
> a redirect). This might of course have some unwanted side-effects that I
> haven't thought of.

I would assume, that this is probably an oversight of mine when I
refactored the login mechanism adding the AuthenticaitonService.login
method.

I created SLING-1032 [1] to track this and fix it by calling login if
anonymous access is not allowed. And fixed in the engine bundle in Rev.
791120.

IIRC we keep the LoginServlet for backwards compatibility and for an
easy entry point into generic system login. As such the LoginServlet
should be accessed from the outside and not from within.

Regards
Felix

[1] https://issues.apache.org/jira/browse/SLING-1032

Re: Why does SlingAuthenticator redirect to LoginServlet?

Posted by Magnus Johansson <kk...@gmail.com>.
Hi

Thanks for your answer... it all makes sense except for one small detail

If I try to follow the code this is my understanding:

 1. SlingAuthenticator calls my AuthenticationHandler.authenticate
 2. AuthenticationHandler.authenticate return null as no user is currently
logged in
 3. SlingAuthenticator will now call SlingAuthenticator.getAnonymousSession
 4. SlingAuthenticator.getAnonymousSession will redirect to LoginServlet
 5. LoginServlet will call AuthenticationHandler.login (via
SlingAuthenticator)

In step 5 my AuthenticationHandler can not get the original request uri that
was requested
by the user at 1 because of the redirect in step 4.

One solution/hack in my AuthenticationHandler would be in step 2 to return
incorrect
credentials instead of returning null. This would force SlingAuthenticator
to call handleLoginFailure and
thus login on my AuthenticationHandler. However, this would mean that I
"loose" the built-in
support for anonymous users.

The other solution would be for step 4 to actually call
AuthenticationHandler.login directly (without
a redirect). This might of course have some unwanted side-effects that I
haven't thought of.


Regards
Magnus Johansson

Re: Why does SlingAuthenticator redirect to LoginServlet?

Posted by Felix Meschberger <fm...@gmail.com>.
Hi,

Magnus Johansson schrieb:
> Hi
> I'm very new to sling so please forgive me if this is a stupid question.

Welcome ! And the question is not stupid at all..

> 
> I'm trying to implement form based authentication as an alternative to http
> basic Authentication.
> As far as I understand SlingAuthenticator will redirect to
> /system/sling/login if the user is not
> yet logged in and anonymous access is not enabled. The LoginServlet will
> then call login on the
> AuthenticationHandler (via SlingAuthenticator). This causes some problems
> for me where I
> want a successful authenticaton to redirect the user back to the original
> page he tried to access.

Actually, what happens is this:

  * Request comes in
  * SlingAuthenticator selects an AuthenticationHandler
  * AuthenticationHandler.authenticate is called
  * The result is used to login
  * On success a session is acquired and all is well
  * On failure, the requestAuthentication method of the
         same AuthenticationHandler is called.

Now, it is the task of the requestAuthentication method to do what is
right for its needs for authentication. It may (as we do in our
closed-source application) redirect to a login page to render the form
and handle the login process. Now this redirect should bear the
originally requested page path - we do this with a request parameter on
the redirect URL as in:

   path/to/login.html?requested=/path/to/requested/page.html

Now the login form can use the user entry to craft the request to login
the user. There are multiple options for this:

  * use AJAX from the form and reload the client document with the
    request URL on success
  * place another request to the originally requested URL adding any
    required parameters to succeed the login

> 
> When the login method on my AuthenticationHandler is called there is no way
> to get the original uri,
> as the user has just been redirected to /system/sling/login
> 
> My question is thus, why does SlingAuthenticator redirect to the
> LoginServlet instead of
> just calling login on the appropriate AuthenticationHandler (this is what
> LoginServlet does anyway).
> If this was the case I could easily temporarily store the original uri in a
> cookie, session or similar to
> be able to redirect the user back after a successful authentication.
> 
> Another question related to implementing alternate authentication methods.
> Is it possible to register
> servlets (under /system/sling for instance) that does not require the user
> to be authenticated even
> if anonymous access on SlingAuthenticator is disabled.

No, if anonymous access is disabled, all requests must be authenticated
in one way or the other. For more fine-grained control on authentication
I suggest you employ access control on the repository.

Hope this helps.

Regards
Felix

> 
> 
> Regards
> Magnus Johansson
>