RejectedSoftware Forums

Sign up

vibed.web.auth framework and redirection

Hello,

I'd like to use the vibed.web.auth framework for authentication in my vibe.d app. If a user is not authorized to access a certain page, he should be redirected to another page (a custom error page for example, or the login page in my case). At the moment, I'm using the following authenticate method to achieve this:

@noRoute AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    if (!req.session || !req.session.isKeySet("auth"))
    {
        redirect("/login");
        throw new HTTPStatusException(HTTPStatus.forbidden, "Du musst dich erst einloggen");
    }
    return req.session.get!AuthInfo("auth");
}

If you need a full working example, the complete sourcecode can be found at https://git.f3l.de/fsimphy/calendar-webapp/tree/poodinis-mongo. The authenticate method is in the file source/calendarwebapp.d.

While this method seems to work, there are a few issues:

  1. Nothing at all seems to happen with the thrown exception (well, something got to happen, what is it?). I'd like to somehow use and display the Exception msg.
  2. Using authenticate methods, which are not @safe or @trusted is deprecated as of vibed 0.8.0. The redirect function is neither @safe nor @trusted, so my authenticate method can not be @safe. I don't know if it is safe to mark it as @trusted.

To me, it seems as if redirecting is not really intended. This leads me to the question: Is there any better way to do this?

Thanks in advance for your help!

Re: vibed.web.auth framework and redirection

Am 09.08.2017 um 02:55 schrieb Johannes Loher:

Hello,

I'd like to use the vibed.web.auth framework for authentication in my vibe.d app. If a user is not authorized to access a certain page, he should be redirected to another page (a custom error page for example, or the login page in my case). At the moment, I'm using the following authenticate method to achieve this:

@noRoute AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse res)
{
    if (!req.session || !req.session.isKeySet("auth"))
    {
        redirect("/login");
        throw new HTTPStatusException(HTTPStatus.forbidden, "Du musst dich erst einloggen");
    }
    return req.session.get!AuthInfo("auth");
}

If you need a full working example, the complete sourcecode can be found at https://git.f3l.de/fsimphy/calendar-webapp/tree/poodinis-mongo. The authenticate method is in the file source/calendarwebapp.d.

While this method seems to work, there are a few issues:

  1. Nothing at all seems to happen with the thrown exception (well, something got to happen, what is it?). I'd like to somehow use and display the Exception msg.
  2. Using authenticate methods, which are not @safe or @trusted is deprecated as of vibed 0.8.0. The redirect function is neither @safe nor @trusted, so my authenticate method can not be @safe. I don't know if it is safe to mark it as @trusted.

To me, it seems as if redirecting is not really intended. This leads me to the question: Is there any better way to do this?

Thanks in advance for your help!

Since redirection is implemented as returning a particular status code,
it cannot be mixed with other kinds of replies (i.e. the forbidden
response that would otherwise be generated by the thrown exception. If
both is required, you'll have to perform the redirection by setting the
Refresh header of the response object instead (with the appropriate
refresh timeout).

Otherwise, you could pass any error message using a query parameter in
the call to redirect() and then simply return AuthInfo.init;. The
forbidden code would not be reported, but the destination page could
still display the message then.

Re: vibed.web.auth framework and redirection

On Wed, 9 Aug 2017 11:38:24 +0200, Sönke Ludwig wrote:

[...]

Since redirection is implemented as returning a particular status code,
it cannot be mixed with other kinds of replies (i.e. the forbidden
response that would otherwise be generated by the thrown exception. If
both is required, you'll have to perform the redirection by setting the
Refresh header of the response object instead (with the appropriate
refresh timeout).

Otherwise, you could pass any error message using a query parameter in
the call to redirect() and then simply return AuthInfo.init;. The
forbidden code would not be reported, but the destination page could
still display the message then.

Thanks for your Answer. I have a few more questions:

I tried your first suggestion, and it works as expected for me. However, of course this displays the 403 error page (blank page showing Error 403 and the Exception message) before the Refresh timeout runs out. For normal requests, It is possible to set the errorpage with @errorDisplay. Is there any possibility to do this in this case, too?

The second approach also works as expected. But still, the question remains, if it is safe to mark the call to redirect @trusted.

Re: vibed.web.auth framework and redirection

Am 09.08.2017 um 12:20 schrieb Johannes Loher:

On Wed, 9 Aug 2017 11:38:24 +0200, Sönke Ludwig wrote:

[...]

Since redirection is implemented as returning a particular status code,
it cannot be mixed with other kinds of replies (i.e. the forbidden
response that would otherwise be generated by the thrown exception. If
both is required, you'll have to perform the redirection by setting the
Refresh header of the response object instead (with the appropriate
refresh timeout).

Otherwise, you could pass any error message using a query parameter in
the call to redirect() and then simply return AuthInfo.init;. The
forbidden code would not be reported, but the destination page could
still display the message then.

Thanks for your Answer. I have a few more questions:

I tried your first suggestion, and it works as expected for me. However, of course this displays the 403 error page (blank page showing Error 403 and the Exception message) before the Refresh timeout runs out. For normal requests, It is possible to set the errorpage with @errorDisplay. Is there any possibility to do this in this case, too?

Not using an annotation, but you can just render pages from within the
authenticate method, or call other functions of the class to do so.
Setting res.statusCode to forbidden before rendering should also
work as expected.

The second approach also works as expected. But still, the question remains, if it is safe to mark the call to redirect @trusted.

Sorry, I forgot about the trusted issue while replying. I've opened a PR
to mark all those functions as @safe. The only @trusted that is
required is for accessing a TaskLocal when the vibe-core package isn't
used and that also generally has a memory safe API.

https://github.com/rejectedsoftware/vibe.d/pull/1886