[librecat-dev] librecat sso module

Nicolas Franck Nicolas.Franck at UGent.be
Thu Feb 22 14:00:28 CET 2018

Seems valid, but where is /shibboleth/login? I guess somewhere in Dancer?
This is probably the response that you get from the main LibreCat application?

On 22 Feb 2018, at 13:14, Jonathan NORRIS <jnorris at ist.ac.at<mailto:jnorris at ist.ac.at>> wrote:

Ok sure, its basically the standard app.pl file provided in the librecat repo with the addition of the mount for the shibboleth sso module. I've attached it.



On 02/22/2018 01:12 PM, Nicolas Franck wrote:
Your last app proves that there is something wrong in your app.psgi. Can you send me the app.psgi?

On 22 Feb 2018, at 12:46, Jonathan NORRIS <jnorris at ist.ac.at<mailto:jnorris at ist.ac.at>> wrote:

Ah, I was misunderstanding how it worked and was doing it very wrong.

So if I try again using only the mounted url and not creating a new route for /auth/shibboleth, ie, only having:

      mount "/auth/shibboleth" => LibreCat::Auth::SSO::Shibboleth->new(
          uri_base => $uri_base,
          authorization_path => "/shibboleth/login",

Then again I am getting a 404. The url /auth/shibboleth is 404ing, so I believe the 'mount' is not working. I get no errors when I start the application and none when I request the url, just a 404.

Why the mount does not work I do not know.

I tested it with a simple mount:

      mount "/testurl" => sub {
          print STDERR "testurl\n";
          [ 302, [ "Location" => "/department" ], [] ];

Still I only get a 404.

And I don't have the old SSO files in the librecat repo, I just have a layer with the files from the SSO module in it. I just copied them there, but in the future I will probably symlink them from the SSO module repo.



On 02/22/2018 11:47 AM, Nicolas Franck wrote:
The method "to_app" returns a PSGI application, which is a sub reference. This sub is used as callback when
a request comes in. Plack sends the current environment to this sub:

   builder {

     mount "/test" => sub {

        my $env = shift;
        #return PSGI compliant response
        [ 200, [ "Content-Type" => "text/plain" ], [ "hello" ] ];



So it is strange that you return a psgi application as your dancer response.

Maybe create an extra mount for the authorization

    mount "/authorize/shibboleth" => sub {

          my $env = shift;
          my $session = Plack::Session->new($env);
     my $auth_sso = $session->get("auth_sso");
          my $uid = $auth_sso->{uid};
          #..search or create Lludss::User and keys to $session

          #redirect to root
          [ 302, [ "Location" => "/" ], [] ];

P.S. A question: are the "old" LibreCat::Auth::SSO files still in your LibreCat repo? Maybe there is a mix going on or something like that.
If they do, try to delete them from the LibreCat repo, and see what happens.
I don't know how you managed to use a git repo inside this project ;-)

On 22 Feb 2018, at 11:25, Jonathan NORRIS <jnorris at ist.ac.at<mailto:jnorris at ist.ac.at>> wrote:

Hello Nicolas,

So far I have all the pieces of code in place for the shibboleth module to work. And I have shibboleth itself configured to work with my application. But I am having trouble with the code that gets the shibboleth environment variables and makes a dancer session.

I have the path '/auth/shibboleth' mounted in my app.pl like so:

  builder {
      enable '+Dancer::Middleware::Rebase', base => $uri_base, strip => 0 if is_string( $uri_base );
      enable 'Deflater';
      enable 'Session',
          store => require_package( $session_store_package )->new( %$session_store_options ),
          state => require_package( $session_state_package )->new( %$session_state_options );

      mount "/auth/shibboleth" => LibreCat::Auth::SSO::Shibboleth->new(
          uri_base => $uri_base,
          authorization_path => "/shibboleth/login",

      mount '/' => $app;

According to the Plack::Builder documentation I must use 'mount '/' => $app' if I use any mounts in the builder.

But after I authenticate successfully with shibboleth and get redirected back to /auth/shibboleth I get a 404. So the mount is not working for some reason.

So I created a route in LibreCat::App (App.pm) like so:

  get '/auth/shibboleth' => sub {
    my $uri_base = Catmandu->config->{uri_base} // Catmandu->config->{host} // "http://localhost:5001"<http://localhost:5001/>;
        uri_base => $uri_base,
        authorization_path => "/shibboleth/login",

This function gets called on the redirect to /auth/shibboleth but initially the code in 'to_app' was not working. Until I removed the 'sub' like so:


  sub to_app {
    my $self = $_[0];
    # sub {
          rest of code
    # }

Then the code inside was ran, but not in the intended way. Its gets as far as far as line 85:

  my $request = Plack::Request->new($env);

Where it fails with the error message: $env is required at line 85. When I print the $env variable with Data::Dumper it looks like:

  $VAR1 = bless( {
                 'authorization_path' => '/shibboleth/login',
                 'uri_base' => 'https://librecat.dev.ist.ac.at<https://librecat.dev.ist.ac.at/>'
               }, 'LibreCat::Auth::SSO::Shibboleth' );

Im guessing that the $env variable (my $env = $_[0];) is wrong due to the fact that I am running the code in an unexpected way. Do you have any ideas on why this is not running correctly, or how to get the mounted url to work in app.pl?

Thanks again for any help!
Much appreciated.


On 02/20/2018 11:21 AM, Nicolas Franck wrote:

Hi Jonathan,

Yes ;-). In the authorization route you will need to translate the session["auth_sso"] into
a valid session containing these keys:

* session["user"]: login user name
* session["user_id"]: login id (user and user_id can be the same)
* session["role"]: choose from "super_admin", "reviewer", "project_reviewer", "data_manager" and "delegate"
* session["lang"]: "en"

(I copied this from lib/LibreCat/App.pm)

Luckily in LibreCat users and their publications are loosely coupled using the user_id from the session as a link, so there is no need to add internal users.
You can just invent your own users at runtime.

For now you will need to do your own whitelisting (if needed), probably using an own Catmandu store:

    my $users = Catmandu->store("main")->bag("shibboleth_users");

in config/catmandu.local.yml you can add your own Catmandu stores (familiar with them?)

P.S. did you make the example app1.pl work with CAS?

On 20 Feb 2018, at 10:51, Jonathan NORRIS <jnorris at ist.ac.at><mailto:jnorris at ist.ac.at> wrote:

Hey Nicolas,

Thank you for your reply. From spending some time reading the code I am starting to see how it works a bit (I should say that I have very little experience with Perl and Dancer so it takes me a little longer) but I still have some questions around how to integrate it with LibreCat as it currently is.

I will just go through the flow of how I think the code works and ask some questions along the way.

In your example app1.pl file in the 'builder' there are various routes defined using 'mount'. To me it looks like this allows the routes to be accessible and the code to be ran when the routes are requested by the browser. In the LibreCat app.pl file I would add a mounted route (/auth/shibboleth) to execute the shibboleth.pm code (the 'to_app' sub). I would have apache config that redirects to the shibboleth authentication page and when the user authenticates shibboleth will redirect back to the '/auth/shibboleth' route. The code executed at this route will check if the shibboleth headers are set and set the 'auth_sso' session vars if it is.

Then there is a redirection to the 'authorization_path', which in the example app1.pl is another mounted route called '/authorize'. Which looks like it just checks for the 'auth_sso' vars and if found tries to find the user profile using the uid set in 'auth_sso', if the user is found it is set in the session and redirected to some desired route.

I believe that to have it work with LibreCat I need to combine the example code that checks for 'auth_sso' with the 'post /login sub' in LibreCat::App. This code authenticates with the local strategies, gets the user and sets the user roles and other session vars. I think that instead of authenticating with a local strategy I just do the 'auth_sso' checking here and then set the user and session vars as normal.

Does this sound like the correct approach or am I conceptually wrong here?

Thanks agian for any help!


IST Austria

On 02/14/2018 04:44 PM, Nicolas Franck wrote:

Hi Jonathan,

Yes I am, and for the moment I am the only person working on this project.
It requires some review, which hasn't been done yet. I'm also on the librecat email list.
So feel free to post questions there about this module.

This functionality is not functional yet in the main repo "LibreCat".
A few months ago they asked me to write functionality for single-sign-on authentication.
First I added some packages to the repo "LibreCat", but soon I realized that the functionality could
be reused, and I created the repo "LibreCat-Auth-SSO". That's why you would see
packages like LibreCat::Auth::SSO in the main librecat repo. But those are old, and
should be removed once the code from LibreCat-Auth-SSO is posted on CPAN.

But as I said, it needs some review, in my opinion.
Have you tried the examples (see README below)? Those explain how it works.

What should happen:

* someone should review the current repo LibreCat-Auth-SSO
* the repo should be posted on CPAN
* the repo should be added to cpanfile of librecat
* extra routes should be added to librecat for authentication and authorization for every single-sign-on type (from config?)

The simplest part is the authentication: the repo already provides plack applications for those.
The authorization has to be done by a route of the application itself, that knows how to translate
an authenticated user into a session.

So I haven't tried LibreCat with Shibboleth. But I did manage to setup an example
plack application with shibboleth. For an example see the perl documentation
in Plack::Auth::SSO::Shibboleth ( starting at "GLOBAL SETUP" ).

As the documentation explains, this module does not do the actual authentication:
the authentication is done by the shibboleth provider from apache. The shibboleth provides
sents the attributes to the backend application either by header (default) or by parameter.

So a plack application can only use shibboleth when used a backend application behind apache.

On 14 Feb 2018, at 16:09, Jonathan NORRIS <jnorris at ist.ac.at><mailto:jnorris at ist.ac.at> wrote:

Hello Nicolas,

Are you the same Nicolas Franck who wrote this SSO module for LibreCat? https://github.com/LibreCat/LibreCat-Auth-SSO

If so I was wondering if you would be willing to help me integrate this module into my LibreCat setup so I can use Shibboleth for authentication.

First I have a couple of questions:

- Have you every configured LibreCat to use the SSO module with Shibboleth?

- Are you the only person to have worked on this module or have the other LibreCat developers also worked on it?

- Are you on the LibreCat dev mailing list, and would my queries about this module be best posted to this mailing list?

I am a developer working for the Institute of Science and Technology Austria and am trying to configure LibreCat for our needs. So any help is greatly appreciate by me and the institute :)



IST Austria


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.uni-bielefeld.de/mailman2/unibi/public/librecat-dev/attachments/20180222/af3b7ac2/attachment.html>

More information about the librecat-dev mailing list