2

For a given application I have a .aspx login form backed by a C# code behind file.
In the code behind I am using the following "home grown" method:

private bool AuthenticateUser(String username, String password)
{
    bool validated = false;
    try
    {
        PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domnet.domad.com", "dc=domnet,dc=domad,dc=com");
        IdentityType ADElement;
        UserPrincipal up;

        //Try first with no @DOM.COM - this should work for SamAccountName values:                 
        username = username.ToUpper().Replace("@DOM.COM", "");
        ADElement = IdentityType.SamAccountName;
        up = UserPrincipal.FindByIdentity(pc, ADElement, username);
        validated = pc.ValidateCredentials(username, password, ContextOptions.Negotiate);

        //If SamAccountName fails try UserPrincipalName with @DOM.COM
        if (!validated)
        {
            username = username + "@DOM.COM";
            ADElement = IdentityType.UserPrincipalName;
            up = UserPrincipal.FindByIdentity(pc, ADElement, username);
            validated = pc.ValidateCredentials(username, password, ContextOptions.Negotiate);
        }

        //Put username into session
        if (validated)
        {
            Session["Username"] = username.Replace("@DOM.COM", "");
        }
    }
    catch (Exception) //login failure...
    {
        validated = false;
    }

    return validated;
}

This works fine for the application but I have other applications that need authentication too.
I really don't want to copy / paste the login files into ever application.

So my most basic question is what are my options to centralize the authentication code between applications?

In the future I will also be looking to:
Verify not only username/password but also AD group membership.
Once user is authenticated no more log in screens between apps. (SSO)

It seems to me I am not the first person to run into this problem.
I would prefer to use an out of the box solution vs. developing my own if possible.

Baxter
  • 5,633
  • 24
  • 69
  • 105

5 Answers5

3

You could:

Community
  • 1
  • 1
Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
  • This sounds like the route I am looking for. Do you know where I could find a book / documentation / sample code for achieving this? – Baxter Oct 23 '12 at 19:20
  • @Baxter - I added some links for you – Louis Ricci Oct 23 '12 at 19:25
  • +1 These approaches may be harder to implement than the one I have suggested, but they offer a much nicer centralization. – Avada Kedavra Oct 23 '12 at 19:26
  • @LastCoder Thank you for the resources! I will definitely dig into them. – Baxter Oct 23 '12 at 19:32
  • @Avada Kedavra - Windows authentication is very easy, turn it on in IIS and edit the authentication mode in your web.configs – Louis Ricci Oct 23 '12 at 19:32
  • @LastCoder: Yes, Windows authentication is easy to setup. The last two looks a bit trickier though.. – Avada Kedavra Oct 23 '12 at 19:36
  • @LastCoder These apps are not necessarily guaranteed to be internally used only. The server they are on is public facing. Will that be an issue if I set my web.config to use windows authentication? – Baxter Oct 23 '12 at 19:47
  • @Baxter - This has already been answered on SO http://stackoverflow.com/questions/651531/windows-authentication-for-intranet-internet – Louis Ricci Oct 23 '12 at 19:52
2

One approach would be to create a Core project (.dll/library) that contains the common parts that you wish to share between your applications, and then to reference that project in your applications.

Ie: Say that you have 2 applications: A and B you would create three projects A, B and Core. In project A and B simply add a project reference to the Core library. Now you can access any method in core from both A and B.

This approach works well with SVN and similar version control systems and you will find it is a very flexible way of working. The hard part is to identify what is really common code and and to make as general as possible.

Avada Kedavra
  • 8,523
  • 5
  • 32
  • 48
  • What if I need to make a change to the authentication method in the Core project? Would I need to remove the reference from application A and B and re-add it / rebuild them against the new Core library? – Baxter Oct 23 '12 at 19:23
  • You only need to rebuild, no need to re-add the reference. – Avada Kedavra Oct 23 '12 at 19:24
2

@Baxter Not sure if my answer comes a bit late as this question was posted a few days ago, but am looking into the same problem of implementing centralized session and authentication management in my MVC 3 application, and I believe the following link would be of great interest to you: http://www.codeproject.com/Articles/246631/ASP-NET-MVC3-Form-Authentication

The author of the article corresponding to the link above, factors out the authentication functionality into a separate DLL and uses dependency injection to use application context to utilize the external 'security' DLL. I am planning to use this approach to centralize the security mechanism and reuse it in 3 different MVC 3 web applications, so it is still research in progress, and will update this answer accordingly with what i find :)

1

You can refactor this method out into a separate project (meaning a different dll) and reference that project from any web application where you want to use this code.

TweeZz
  • 4,779
  • 5
  • 39
  • 53
  • Would I need to include the .dll in each web application project and rebuild them all? What if I need to make a change to the .dll will I have to include the updated .dll and rebuild every web application. If so, that is almost as cumbersome as copying and pasting the form / class to each app. – Baxter Oct 23 '12 at 19:18
  • Not so much really. If you limit the functionality of this dll to only performing authentication, once you have the kinks worked out, it should never need to be changed, unless you are completely redoing how you are performing authentication. – Kevin Oct 23 '12 at 19:35
  • Was just thinking, having a central authentication library becomes an adventage if you are changing the authentication. You change the library and rebuild it, but everything using it only needs a recompile. – Kevin Oct 23 '12 at 19:42
0

An alternative if you are using Windows Authentication is to grab their SID, query AD for a piece of information that is shared between AD and the application's user table (we use the email address) and check to see if the user table has an entry with that email address.

This way, by logging onto their workstation, they are essentially pre-logged into any application using this authentication method. You just have to make sure that when you create a new user account (at the application level) you capture the info that you want to check for authentication (this is why we use the email address - everyone knows their company email).

This works really well with the Core library method suggested by Avada Kedavra. This method also allows you to have each application maintain its own user base (although it will also work well with a central user database).

Kevin
  • 704
  • 3
  • 4