adding LDAP Auth backend

51 views
Skip to first unread message

Neal N. Wang

unread,
Aug 8, 2012, 5:49:13 PM8/8/12
to snap_fr...@googlegroups.com
Hi folk,

I wand to add LDAP auth backend to Snap.Snapplet.Auth. In LDAP authentication, the user and password are sent to LDAP server, and the provided password is compared with stored one in LDAP server.  It's not possible to add an instance of IAuthBackend for LDAP.

Any suggestion how to make Auth work with LDAP backend?

Thanks,
Neal

mightybyte

unread,
Aug 9, 2012, 1:17:08 PM8/9/12
to snap_fr...@googlegroups.com
Hi Neal,

I'm not familiar with LDAP authentication, so I'm not sure how to go about modifying our interface to allow LDAP.  We do want this auth snaplet to be as general as possible while still being reasonably simple for the end user.  If you would like to implement an LDAP auth backend, we'll be happy to work with you on this.  We're in #snapframework or freenode IRC if you want to have a more interactive discussion.  If you prefer the mailing list, maybe you could write a more detailed analysis of how the current API is lacking and some ideas about what changes we would need to support an LDAP backend.

Neal N. Wang

unread,
Aug 9, 2012, 3:03:54 PM8/9/12
to snap_fr...@googlegroups.com
As party of my effort to quickly hack a LDAP auth solution,  I thought I can replace Auth.loginUser  with my implementation and get it working.  I did this experiment.   Replacing Auth.loginUser in the "snap init" example with a dummy myLoginUser which already returns AuthUser.  I was expecting this will allow any user to login, but it does not and redirect me to login page without error.  

What is wrong here?

ldapAuth :: ByteString -> ByteString -> Handler b (AuthManager b) (Either AuthFailure AuthUser)
ldapAuth username password = do { ld <- liftIO (ldapInit hostname port)
                                ; liftIO (putStrLn ("ldapAuth is called  with" ++ (BC.unpack username) ++ " and " ++ (BC.unpack password)))
                                ; return $ Right (defAuthUser { userLogin = T.pack $ BC.unpack username })
                                }


myLoginUser
  :: ByteString
  -- ^ Username field
  -> ByteString
  -- ^ Password field
  -> Maybe ByteString
  -- ^ Remember field; Nothing if you want no remember function.
  -> (AuthFailure -> Handler b (AuthManager b) ())
  -- ^ Upon failure
  -> Handler b (AuthManager b) ()
  -- ^ Upon success
  -> Handler b (AuthManager b) ()
myLoginUser unf pwdf remf loginFail loginSucc =
    runErrorT go >>= either loginFail (const loginSucc)
  where
    go :: ErrorT AuthFailure (Handler b (AuthManager b)) AuthUser
    go = do { mbUsername <- getParam unf
            ; mbPassword <- getParam pwdf
            ; password <- maybe (throwError PasswordMissing) return mbPassword
            ; username <- maybe (fail "Username is missing") return mbUsername
            ; ErrorT $ ldapAuth username password
            }


Thanks,
Neal

--
 
 
 

mightybyte

unread,
Aug 9, 2012, 3:26:55 PM8/9/12
to snap_fr...@googlegroups.com
loginUser calls loginByUsername, which checks that the password is correct and then sets the session cookie that is expected by the other auth API functions.  We anticipated use cases like this and provide the forceLogin function which sets the session cookie without verifying the password.  After you verify that the login is correct with LDAP, you need to call forceLogin to actually log the user in.
Reply all
Reply to author
Forward
0 new messages