1

I know this is a super novice question, but I'm having a tough time understanding this. I'm implementing WebSecurity in my n-tier application. I've placed all WebSecurity code in my repository layer (closest to the db layer).

I have code like this:

public bool LogIn(string userName, string password, bool rememberMe)
    {
        return WebSecurity.Login(userName, password, rememberMe);
    }

public void LogOut()
    {
        WebSecurity.Logout();
    }

WebSecurity doesn't need to know the context for logging in - I pass the parameters. But what about logging out? With 10 users logging out, how does this code right here know which user to log out? Does the context of the user somehow get pushed all the way down to the repository layer, from the browser client to my API controller, through my services layer?

SB2055
  • 12,272
  • 32
  • 97
  • 202
  • 2
    I think you should create separate service class for authentication purpose. To see difference between repository and service, please read this question: http://stackoverflow.com/questions/5049363/difference-between-repository-and-service-layer/5049454#5049454. This service layer method should have `IPrincipal` injected. `IPrincipal` interface stores information about current user. `HttpContext.Current.User` implements it. – LukLed Apr 17 '13 at 21:46

2 Answers2

3

I would create service class to implement this functionality. This service layer method should have IPrincipal and IUserRepository injected. IPrincipal interface stores information about current user. HttpContext.Current.User implements it.

public interface IAuthenticationService
{
    bool SignIn(string userName, string password, bool rememberMe);
    void SignOut();
}

public class WebSecurityAuthenticationService : IAuthenticationService
{
     public WebSecurityAuthenticationService(IPrincipal user, IUserRepository userRepository)
     {
     }

     ....implementation...
}

You should use IOC container to define binding between IPrincial and HttpContext.Current.User and between IUserRepository and its database based implementation. I recommend Ninject, but choice is yours.

LukLed
  • 31,452
  • 17
  • 82
  • 107
2

Your repository layer shouldn't know which user is logged in. Your repository layer shouldn't even know that there is a user. All of your authentication should be handled by your web application - your web application then, having authenticated the user, accesses your repository layer, which simply does whatever it's told to do and doesn't concern itself with authentication.

Update: As John Saunders points out, this would not tie your web application to the membership database/tables but to the membership system you are using. If even this is too tightly-coupled for you, you could think about defining an IMembershipService interface, which you pass into your controllers' constructors (potentially via dependency injection). You would then create a concrete implementation of IMembershipService that implements Login and Logout via WebSecurity.

This way, if you decide you want to implement membership in a completely different way, your only restriction is that your replacement membership service must implement IMembershipService - you can change the technology and data structures entirely and your web application is none the wiser.

Ant P
  • 24,820
  • 5
  • 68
  • 105
  • Doesn't this mean that the Web Application is tightly coupled to the Membership tables (aka database)? Is that ok? – SB2055 Apr 17 '13 at 21:44
  • 2
    No, the web application is tied to the membership subsystem, which worrys about tables and such – John Saunders Apr 17 '13 at 21:51