views:

346

answers:

5

User Login functionality is very common to many applications. I would like to see how people implement this functionality in Object oriented way.

I have a User and I need to validate the userId and password against a system(this could be ldap, database, etc.). So what kind of classes and operations you would create to achieve this functionality?

Or is OO a bad choice to develop this functionality?

I am about to start a new project so want to gather good options.


I know there are frameworks which provide this solution already. I have used them in earlier projects. What I was trying to see is how people implement this in OO way.

I read the answers and everybody suggested a separate Credentials and Authentication Service. If instead of Credentials I use class name as User then shouldn't User class should have a method called login? Just like a Person object will have a method drink instead of DrinkService or I am wrong in understanding this correctly?

+2  A: 

Exactly how extensible does it need to be? I'd define an abstract class, Credentials, that encapsulates the needed authentication information for a given system. Subclass it for specific system types. An example would be BasicCredentials that contains only username and password. Then, define an interface that defines methods for authentication. Maybe I'd also define an abstract Host class that includes additional host information. This may be too much abstraction, depending on what you envision authenticating against.

This example code is C# 3.0.

public abstract class Credentials
{
}

public class BasicCredentials : Credentials
{
    public String Username { get; set; }
    public String Password { get; set; }
}

public abstract class Host
{
}

public class IPHost : Host
{
    public IPAddress Location { get; set; }
}

public interface IAuthenticate
{
    bool Authenticate(Credentials creds, Host host);
}

public class BasicAuthenticator : IAuthenticate
{
    public bool Authenticate(Credentials creds, Host host)
    {
        // Check to make sure we're given the right type of parameters
        if (creds is BasicCredentials && host is IPHost)
        {
            // Do your magic here
        }
    }
}
Matt Olenik
+2  A: 

If you want an OO solution I'd go for using an OO language and writing some classes ;-).

But seriously, at the basic level you're going to want a databean to store the login information, let's call that "Login". I'd then go for a service that provides authentication, let's call that "AuthenticationService". Finally you can provide concrete implementations of each of the different kind of authentication schemes you need. So you're gonna have something like:

public class Login {
    private String loginName;
    private String password;

    /* getters / setters */
}

public interface AuthenticationService {
    public boolean isLoginValid(Login login);
}

public class LdapAuthenticationService implements AuthenticationService {
    public boolean isLoginValid(Login login) {
        /* LDAP specifics here */
    }
}

public class DatabaseAuthenticationService implements AuthenticationService {
    public boolean isLoginValid(Login login) {
        /* database specifics here */
    }
}

Use dependency-injection to get the required concrete implementation into your system depending on what your current needs are.

MrWiggles
A: 

The object-oriented approach is to use the provided classes or find a library and subclass it if it doesn't already do what you want :)

Robert Grant
No, that's called good engineering. :)
Matt Olenik
+3  A: 

Or is OO a bad choice to develop this functionality?

I don't think usage of OO limits you in any way, so the question should rather be, can I afford building this part with OO? Other styles could be a lot faster.

That having said, I'd create the following classes:

  • Credentials
  • AuthenticationService

Furthermore, the class User would require a getCredentials() function. This approach means, that you're always authenticating using username/password, though. For an even broader approach, let the AuthenticationService operate on the User object itself.

soulmerge
What do you mean by faster? Faster to create?
Matt Olenik
No, faster execution. If the application is meant to be fast and the authentication is used excessively, it could be more effective to handle it in a single function. Ok, excessive usage of authentication *does* sound a bit weird :)
soulmerge
Honestly, I have a real hard time believing OOP vs procedural is ever going to matter for authentication, which is almost always network dependent. That's premature optimization to the extreme.
Matt Olenik
Yeah noticed that while trying to answer your question ...
soulmerge
A: 

Authentication also involves retrieving credentials and you will want to include how the credentials are accessed in your authentication framework. This can be even more important than the Authenticator class already highlighted.

class CredentialsAccessor {
  public bool hasCredentials(){};
  public Credentials getCredentials();
}
class FormAccessor : CredentialsAccessor {
    // get credentials from a webapp or form
}
class CookieAccessor : CredentialsAccessor {
    // get credentials based on cookie
}
class SessionAccessor : CredentialsAccessor {
    // get credentials from user session
}
class CredentialAccessManager 
{
   list<CredentialsAccessor> m_Credentials;

   Credentials getCredentials() 
   {
     foreach( CredentialsAccessor l_accessor in m_Credentials )
     {
         if( l_accessor.hasCredentials() ) return l_accessor.credentials();
     }
   }
}

You plug all the accessor objects into the list in the right order and your user will magically be logged in every time.

SmokingRope