FAQ
Hello,

like in the def. guide 2 catalyst described I've tested a progressive
authentication via DB and LDAP, which worked just fine :-D
But now I have to use an already existing DB, which has different
column-names. As long as I authenticate via a DB everything works,
because I can pass the the column-name as keys:

if ($c->authenticate({ user_identification => $username,
user_password => $password } )) {

Unfortunalty the auth-call doesn't work for the LDAP-auth any more.

Is there a possibilty to map the keys, so they also work for a
LDAP-authentication?
Or do I have to duplicate my code and pass the realm, like:

if ($c->authenticate({ username => $username,
password => $password }, 'ldapAuth'
)) {


thanx :-D

Search Discussions

  • Tomas Doran at Jan 24, 2011 at 10:00 pm

    On 24 Jan 2011, at 15:17, piccard wrote:

    Is there a possibilty to map the keys, so they also work for a LDAP-
    authentication?
    Yes, there is. You'll need to patch the code, but the patch would be
    very welcome upstream.

    Add an authinfo_remap key to the config, and the code...

    if ( my $map = $self->config->{authinfo_remap}->{$realm->name} ) {
    foreach my $from (keys %$map) {
    $auth->{$map->{$from}} = delete $auth->{$from};
    }
    }

    or something similar... Add a couple of tests to that, and you're done..

    Cheers
    t0m
  • Piccard at Jan 25, 2011 at 10:01 am
    Hi,
    Is there a possibilty to map the keys, so they also work for a
    LDAP-authentication?
    Yes, there is. You'll need to patch the code, but the patch would be
    very welcome upstream.

    Add an authinfo_remap key to the config, and the code...

    if ( my $map = $self->config->{authinfo_remap}->{$realm->name} ) {
    foreach my $from (keys %$map) {
    $auth->{$map->{$from}} = delete $auth->{$from};
    }
    }

    or something similar... Add a couple of tests to that, and you're done..

    thank u for your suggestion, maybe I'll try it, when I've got a little
    more time ;-)

    In view of that, I've got one more question. What I would really need,
    is a password authentification against LDAP and if successful,
    get the user and his roles from the database. So, is it possible to
    split up this process and still use methods like check_any_user_role()?

    thanx :-D

    Cheers
    t0m


    _______________________________________________
    List: Catalyst@lists.scsys.co.uk
    Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
    Searchable archive:
    http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
    Dev site: http://dev.catalyst.perl.org/
  • Tomas Doran at Jan 25, 2011 at 10:15 am

    On 25 Jan 2011, at 10:01, piccard wrote:
    In view of that, I've got one more question. What I would really
    need, is a password authentification against LDAP and if successful,
    get the user and his roles from the database. So, is it possible to
    split up this process and still use methods like
    check_any_user_role()?
    I don't think you want the authentication framework to be doing that
    for you.

    If that's what you're _actually_ doing, then putting the
    authentication logic into your user class makes much more sense, and
    makes your data model much more consistent... Otherwise you have to
    replicate the authentication framework if you ever want to log a user
    in (or simulate a 'proper' user, or change password, or..) outside the
    context of the Catalyst application.

    The authentication framework already provides this sort of hook for
    you, with the self_check configuration option, which says that the
    user class is responsible for checking it's own password.

    Cheers
    t0m
  • Piccard at Jan 25, 2011 at 2:55 pm

    Am 25.01.2011 11:16, schrieb Tomas Doran:
    On 25 Jan 2011, at 10:01, piccard wrote:
    In view of that, I've got one more question. What I would really
    need, is a password authentification against LDAP and if successful,
    get the user and his roles from the database. So, is it possible to
    split up this process and still use methods like check_any_user_role()?
    I don't think you want the authentication framework to be doing that
    for you.

    If that's what you're _actually_ doing, then putting the
    authentication logic into your user class makes much more sense, and
    makes your data model much more consistent... Otherwise you have to
    replicate the authentication framework if you ever want to log a user
    in (or simulate a 'proper' user, or change password, or..) outside the
    context of the Catalyst application.
    I'm not sure if I will really run into these problems. I've tried it so
    far this way:

    a user authenticates hisself succesfully via LDAP.
    afterwards the user will be logged out immediately.
    then a dbix find_or_create-routine is going to fetch the user-object
    which I'll use to reauthenticate via DB.

    so I think this could work properly and at least I've got all the
    goodies the authentication-framwork provides. what do you think?

    unfortunately I'm using a 'dirty' hack to authenticate (the DB shouldn't
    safe LDAP-passwords):

    my $user = $c->model('DB::User')->find_or_create({ user_identification
    => $username });
    $c->session->{__user} = { $user->get_columns };

    I would prefer using $c->set_authenticated( $user, 'dbAuth'); but
    somehow it doesn't work for me. I think I just use the wrong user-object.
    The authentication framework already provides this sort of hook for
    you, with the self_check configuration option, which says that the
    user class is responsible for checking it's own password.
    I'm not sure how this should work. the doc says 'self_check indicates
    that the password should be passed to the check_password() routine on
    the user object returned from the store'.
    How or in which way I can set the hook?
  • Tomas Doran at Jan 25, 2011 at 3:54 pm

    On 25 Jan 2011, at 14:55, piccard wrote:
    I'm not sure if I will really run into these problems. I've tried it
    so far this way:
    You will.

    It will come and bite you on the ass, trust me. You are trying to make
    Catalyst (and the authentication framework) take place of your
    business logic code, and that's not what it should be doing.
    so I think this could work properly and at least I've got all the
    goodies the authentication-framwork provides. what do you think?
    That it's a terrible idea. What 'goodies' do you want?

    I'm suggesting just using the DBIC authentication layer as normal in
    Catalyst, so everything will work as normal, with all the 'goodies'.
    unfortunately I'm using a 'dirty' hack to authenticate (the DB
    shouldn't safe LDAP-passwords):

    my $user = $c->model('DB::User')-
    find_or_create({ user_identification => $username });
    $c->session->{__user} = { $user->get_columns };

    I would prefer using $c->set_authenticated( $user, 'dbAuth'); but
    somehow it doesn't work for me. I think I just use the wrong user-
    object.
    Don't do any of that.
    The authentication framework already provides this sort of hook for
    you, with the self_check configuration option, which says that the
    user class is responsible for checking it's own password.
    I'm not sure how this should work. the doc says 'self_check
    indicates that the password should be passed to the check_password()
    routine on the user object returned from the store'.
    How or in which way I can set the hook?
    You set it in the config, you implement a check_password method in
    your user object (which goes and checks the password from LDAP),
    you're done.

    Cheers
    t0m
  • Piccard at Jan 26, 2011 at 1:48 pm

    You set it in the config, you implement a check_password method in
    your user object (which goes and checks the password from LDAP),
    you're done.

    For anybody who is working on the same problem, this solution worked 4 me:

    + set the extended classin the config via the store_user_class-key

    credential => {
    class => 'Password',
    password_type => 'self_check',
    password_field => 'user_password'
    },
    store => {
    class => 'DBIx::Class',
    user_model => 'DB::User',
    store_user_class
    =>'DW::Authentication::Store::DBIx::Class::User',
    role_relation => 'roles',
    role_field => 'role_category',
    use_userdata_from_session => '1'
    },

    + the new class which includes the new check_password-method (i.e.
    authenticate via LDAP but use the roles inside the DB)

    package DW::Authentication::Store::DBIx::Class::User;

    use strict;
    use warnings;

    use Moose;
    use MooseX::NonMoose;
    use namespace::autoclean;
    extends qw/Catalyst::Authentication::Store::DBIx::Class::User/;

    sub check_password {
    my ( $self, $password ) = @_;

    # i.e. LDAP-auth

    return 1;

    }


    __PACKAGE__->meta->make_immutable;
    1;



    ... thanx 2 t0m;-)
  • Tomas Doran at Jan 26, 2011 at 2:53 pm
    On 26 Jan 2011, at 13:48, piccard wrote:
    You set it in the config, you implement a check_password method in
    your user object (which goes and checks the password from LDAP),
    you're done.

    For anybody who is working on the same problem, this solution worked
    4 me:

    + set the extended classin the config via the store_user_class-key
    I don't think you even need to go that far..

    The DBIx::Class::User module will delegate any unknown methods onto
    your user row..

    So you should just be able to add your check_password method onto the
    row object, without having a custom user_class..

    Then you get the initial advantage I was promoting (i.e. your database
    model is internally consistent, and you can use check_password outside
    of a Catalyst context if you want to), and you have less code...

    Cheers
    t0m
  • Piccard at Jan 26, 2011 at 4:27 pm

    I don't think you even need to go that far..

    The DBIx::Class::User module will delegate any unknown methods onto
    your user row..

    So you should just be able to add your check_password method onto the
    row object, without having a custom user_class..

    Then you get the initial advantage I was promoting (i.e. your database
    model is internally consistent, and you can use check_password outside
    of a Catalyst context if you want to), and you have less code...
    yes, u are absolutly right. tested it like this and it worked.

    __PACKAGE__->add_columns(
    'user_password' => {
    encode_check_method => __PACKAGE__->check_password,
    ...


    sub check_password {
    my ($self, $pw);
    ...
    }


    but ... I decided to go for the new extended class because I still need
    progressive Auth, means, some users are only in the DB (including their
    password) and some are only in the LDAP-Dir.
    So, if I go for the example above a normal PasswordCheck against the DB
    wouldn't be possible anymore, right?
  • Tomas Doran at Jan 26, 2011 at 5:22 pm

    On 26 Jan 2011, at 16:27, piccard wrote:

    but ... I decided to go for the new extended class because I still
    need progressive Auth, means, some users are only in the DB
    (including their password) and some are only in the LDAP-Dir.
    So, if I go for the example above a normal PasswordCheck against the
    DB wouldn't be possible anymore, right?
    So put that logic in your domain model (i.e. DB row class), where it
    belongs?

    Cheers
    t0m
  • Piccard at Jan 28, 2011 at 4:34 pm

    So put that logic in your domain model (i.e. DB row class), where it
    belongs?
    sorry, I'm not sure what u mean (new to Catalyst and DBIx).
    I need progressive authentication. First it should check against the db
    and then against the LDAP-dir, but using the roles from the db.
    If I'm going to put the new 'check_password' inside the Result Class I'm
    not able to to check also against the LDAP-Dir:


    __PACKAGE__->add_columns(
    'user_password' => {
    encode_check_method => __PACKAGE__->check_password,
    ...


    sub check_password {
    my ($self, $pw);
    ... LDAP-check ...
    }

    ... or do you mean just shifting the new class to another place?
    from

    store => {
    ...
    store_user_class
    =>'DW::Authentication::Store::DBIx::Class::User',
    ...
    },

    to

    store => {
    ...
    store_user_class
    =>'DW::Schema::Result::DBIx::Class::User',
    ...
    },


    ???

    also I would like to know if it's possible to read the configuration
    from a Model/ResultClass or another class, like the one above
    'DW::Authentication::Store::DBIx::Class::User'?

    thank u very much :-)
  • Tomas Doran at Jan 31, 2011 at 8:06 am
    On 28 Jan 2011, at 16:34, piccard wrote:
    So put that logic in your domain model (i.e. DB row class), where
    it belongs?
    sorry, I'm not sure what u mean (new to Catalyst and DBIx).
    I need progressive authentication.
    No, you don't.
    First it should check against the db and then against the LDAP-dir,
    but using the roles from the db.
    If I'm going to put the new 'check_password' inside the Result Class
    I'm not able to to check also against the LDAP-Dir:
    Yes you are - it's just code... Make the check_password method in the
    result class do the right thing for you.

    Cheers
    t0m

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedJan 24, '11 at 3:17p
activeJan 31, '11 at 8:06a
posts12
users2
websitecatalystframework.org
irc#catalyst

2 users in discussion

Tomas Doran: 6 posts Piccard: 6 posts

People

Translate

site design / logo © 2022 Grokbase