Archive for September, 2007

A Few Accolades

September 26th, 2007

Big props to Marc V. who won his first cross race at Charm City in Baltimore last weekend.

Meanwhile Plesko and Bill did the Tour de Front Range over the weekend, a 60+ mile mountain bike stomp connecting the main front range trails. Plesko put in his usual extra credit, 15 hours and 103 miles makes for a wicked profile:

I also got to see Katie C and Chopko when they used my house to temporarily exchange custody of “their dog” Reese. Chopko was headed up to Alaska on a hunting trip. I warned him to look out for Surviving the Game situation. Katie won her race at Bear Creek on Saturday but was disappointed by her performance. Ahhh, what a problem to have….

Better late than never, my bro’ Joe volunteered 24hrs continuous time to Create-A-Thon. Here’s his recap of that:
Anyway, last week was Create-A-Thon, that yearly benefit where a group of New Jersey and Philly based graphic designers donate a straight 24 hour block of time to create marketing materials for deserving non-profit organizations. This time out, I pulled Habitat for Humanity Philadelphia, who recently worked out a deal with a group of Philly independent fair trade coffee houses (including one of my personal favorites, Mug Shots, (happen who make a great vegan whoopie pie, by the way)) where every time you buy a cup of java, proceeds go to build someone a home. And best of all, Habitat’s been going Green, which is an added plus. Anyone who knows me will tell you this is right up my alley. So please make sure you get your caffeine fix from participating shops this fall. Click here to peep the poster, one of seven pieces I designed for the campaign. And yes, the little house is made out of coffee beans. What a nice smell to come home to, ‘eh!

Congrats to Truesdale’s for his first week of quality blog posts. Much better quality than what I spew…

Myself, I’m still holding steady at 180 lbs, even as my body atrophies. But we’re right on the cusp of the dark period of time I call the Season of Glutiny: October 31st to January 1st. Damn I’ve got to get back on my bike…

Active Directory Authentication Part I

September 25th, 2007

One of the main reasons I started this blog was so that I would have a place to “give back” to the software development community. For those that read my blog for more personal updates, you’ll want to stop here. My daily work life depends heavily on open source projects, discussion forums and blogs posts like this one. In this post I’ll be sharing what I’ve learned regarding programmatic authentication to Active Directory for a custom website authentication scheme.

I recently redeveloped a centralized web-based authentication service for a large corporate intranet that leveraged RSA Access Manager as a web single sign-on (SSO) provider. The authentication service validates credentials against Active Directory and handles cases of expired password resets and locked accounts. Once a credential has been validated, the user Id is asserted to RSA Access Manager, creating a new session and then passing control over to RSA and redirecting onto the requested resource.

A few key points:

  • RSA Access Manager is a Java based application and all of the intranet applications are Java applications
  • The Active Directory forest has 42 child domains organized by business unit, all de-centrally administered, spread across the US in 18 states and connected by a wide area network with relatively high latency.
  • Across the 42 domains, there are well over 100 domain controllers, some Windows 2003, others Windows 2000
  • As I am a Java developer with no previous .Net experience, the first attempt to externalize authentication from RSA Access Manager was in Java via JAAS/GSS-API and then JNDI. Without going into detail, this turned out to be difficult given the diversity of the AD infrastructure.

    Next, since we had other needs to interface with Active Directory from our applications, I decided on a new approach. I developed a .Net Web Services API in C# to interface with our Active Directory infrastructure. The Web Services API encapsulated the complexity of the environment and allowed the caller to search, retrieve, and manipulate AD users and group information. This is now how we integrate our Java applications with AD. As part of this implementation in the same ASP.Net web application, I implemented the centralized authentication HTML service. Next I’ll dive into three iterations of the authentication functionality. I’ll save anything outside of the authentication portion for other posts if there’s interest.

    The first iteration leveraged Integrated Windows Authentication (IWA) via IIS. I won’t go into detail on this but will say we abandoned that approach because of the regular use of shared workstations and auto-login accounts.

    The second iteration used LDAP via ADSI:
    Given a domain, samAccountName and password, attempt to bind to the root of the domain of the user. If successful, continue. If the bind failed, one of these cases is true: the credential was invalid, the account password is expired (including “must change password on next login” situations, the account is locked (too many bad attempts) or the account is disabled. Therefore, bind with a known system credential to check the account status. If the account password is expired, notify the user and prompt the user to reset their password. Otherwise, if the account is locked, disabled, or looks OK, return that the authentication was unsuccessful.

    Below are several snippets of code:

    public static AuthenticationResult authAndStatus(string domain, string samAccountName,
        string password, String adminUsername, String adminPassword)
    {
        String domainAndUsername = domain + "\\\\" + samAccountName;
        DirectoryEntry de = getDirectoryEntry(domain, domainAndUsername, password);
        AuthenticationResult result = new AuthenticationResult();
        DirectoryEntry userDE = null;
    
        try
        {
            // Bind to the native AdsObject to force authentication.
            Object obj = de.NativeObject;
            result.authResult = AuthenticationResult.SUCCESSFUL;
    
        }
        catch (Exception ex)
        {
            // the bind failed
            result.authResult = AuthenticationResult.FAILED;
        }
    
        try
        {
            // get the account status
            de = getDirectoryEntry(domain, adminUsername, adminPassword);
            userDE = ADUtilities.getUserDE(de, "samAccountName", samAccountName,
                adminUsername, adminPassword);
            if (userDE != null)
            {
                AccountStatus accountStatus = new AccountStatus(userDE);
                result.accountStatus = accountStatus;
            }
            else
            {
                result.authResult = AuthenticationResult.INVALID;
            }
        }
        catch (Exception ex)
        {
            // need to trap, basically don't let the status check break
            //the authentication
        }
    
        return result;
    }
    
        public static DirectoryEntry getUserDE(DirectoryEntry de, String propertyName, String propertyValue, String adminUsername, String adminPassword)
        {
            DirectorySearcher search = new DirectorySearcher(de);
            search.Filter = "(" + propertyName + "=" + propertyValue + ")";
    
            SearchResult result = search.FindOne();
            if (result != null) {
                return new DirectoryEntry(result.Path, adminUsername, adminPassword);
            } else {
                return null;
            }
        }
    
    public static DirectoryEntry getDirectoryEntry(String domain, String adminUsername, String adminPassword)
    {
        String dePath = null;
    
        String adForestName = (String)System.AppDomain.CurrentDomain.GetData("adForestName");
        String forestDomainName = adForestName.Substring(0, adForestName.IndexOf('.'));
        String gcDNS = (String)System.AppDomain.CurrentDomain.GetData("adForestPreferredGlobalCatalog");
    
        if (domain != null && domain.ToUpper().Contains(".") && domain.ToUpper().Contains(adForestName.ToUpper()))
        {
            domain = (domain.Split(new char[] { '.' }))[0];
        }
    
        // if the domain is not null and not All
        if (domain != null && !domain.Trim().Equals("") && !domain.Equals("All"))
        {
            String fqdn = domain + "." + adForestName;
    
            // check if this is the root domain and if so rest the fqdn to the forest name
            if (domain.ToUpper().Equals(forestDomainName.ToUpper()))
                fqdn = adForestName;
    
            String ldapDCs = getLDAPDCs(fqdn);
            dePath = "LDAP://" + fqdn + "/" + ldapDCs;
    
        }
        else
        {
            String ldapDCs = getLDAPDCs(adForestName);
            // if the domain is null assume the global catalog
            dePath = "LDAP://" + gcDNS + ":3268/" + ldapDCs;
        }
    
        DirectoryEntry de = new DirectoryEntry(dePath, adminUsername, adminPassword, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
        return de;
    
    }
    
    public static DirectoryEntry getGCDirectoryEntryForDomain(String domain, String adminUsername, String adminPassword)
    {
        String dePath = null;
    
        String adForestName = (String)System.AppDomain.CurrentDomain.GetData("adForestName");
        String forestDomainName = adForestName.Substring(0, adForestName.IndexOf('.'));
        String gcDNS = (String)System.AppDomain.CurrentDomain.GetData("adForestPreferredGlobalCatalog");
    
        dePath = "LDAP://" + gcDNS + ":3268/" + getLDAPDCs(domain + "." + adForestName);
    
        DirectoryEntry de = new DirectoryEntry(dePath, adminUsername, adminPassword, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
        return de;
    
    }
    
    public static String getLDAPDCs(String fqdn)
    {
        String ldapDCs = "";
    
        if (fqdn != null) {
            char[] separator = new char[1];
            separator[0] = '.';
            String[] parts = fqdn.Split(separator);
    
            for (int i = 0; i < parts.Length; i++) {
                ldapDCs = ldapDCs + "dc=" + parts[i];
    
                if (i + 1 != parts.Length)
                    ldapDCs = ldapDCs + ",";
            }
        }
    
        return ldapDCs;
    }
    

    In my next post I describe how well this approach actually worked and the issues that prompted the search for another solution. Then I'll go into using SSPI and then the use of the LogonUser native function call...

    I FINALLY posted a follow-up to this here

    Post Op

    September 20th, 2007

    I had my post op follow up today, and my shoulder is looking good. Check out the x-ray, it’s pretty gnarly… six screws and a plate. Just 4 more weeks left in a sling and then another month+ of laying low. I hope to be back on the trainer (w/ sling) next week.
    img063.jpg

    International Talk Like a Pirate Day

    September 19th, 2007

    I pop online this morning, start up meebo in a Firefox tab and see this blog post as I log in explaining how meebo is celebrating Talk Like a Pirate Day with pirate emoticons and a Pirate Speak translator for IM conversations. Little did I know that this was an “international” holiday.

    Ten minutes later, my bro’ Ken sends me a message…

    [07:53] Ken Brevoort: Ahoy, ye scurvy dog! And a happy International Talk like a Pirate day to ye'.
    [07:57] mikebrevoort: Ha ha, I be jus' readin' somethin' about that... pretty funny
    [08:08] Ken Brevoort: Have you not heard of it before?
    [08:11] mikebrevoort: No, first time. I can't believe I've been in the dark this long.
    [08:17] Ken Brevoort: Yeah, I've been celebrating for several years now.

    Later in the day I'm ripping through my feeds with Google Reader, and I come across this post from Mike Cannon-Brookes (Aussie, co-founder of Atlassian) highlighting how ticked he was that Flickr was humorously celebrating Talk Like a Pirate Day. Speaking of Aussies and Pirates, I'm suspicious that Cannon-Brooks is actually Captain Feathersword of the Wiggles. You do the math...
    Captian Feathersword

    This had me wondering what other "B" holidays I've been missing. I found this list of thirteen.

    By the way, if anyone's looking for a new Festivus Pole, I've got you covered.

    In recognition to Talk Like a Pirate Day, you can read this post in Pirate.... ARGGH!

    Ephraim’s Birthday

    September 17th, 2007

    Ephraim TrumpetSunday was Ephraim’s birthday, and we celebrated in typical American style, with cake and excess gifts. In Nigeria they only celebrate birthdays to age 12 so Ephraim hasn’t had a birthday celebration in five years. Back in Nigeria, Ephraim plays the trumpet at his church but he shares the trumpet with 3 others and has to share time to practice. Since coming to the US he’s really missed playing the trumpet and is interested in joining the band at school this spring, but no trumpet. Jeanie searched endlessly and managed to find a great used trumpet on craigslist. This was the highlight of the day, Ephraim receiving his own trumpet. He was so excited!

    The Incision

    September 16th, 2007

    img_0075.JPG

    Recovering Slowely

    September 16th, 2007

    I feel like my ass is starting to spread out like melting wax on hot pavement; I’ve been camped out in a recliner for the majority of the last 3 days. I was able to take my bandage off today and tomorrow I can actually take a shower. Big milestones! The far right side of my chest has lost nerve sensitivity. My surgeon warned me of this, but it’s still feels weird. He said there was no way around it. The good news is that everything else appears to be tip-top.

    All things considered I had a really good experience. The staff and facilities at St. Anthony’s was great and Dr. McNair delivered the goods and had a great bedside manner.

    I can’t wait to move onto other subject matter…

    Surgery Successful

    September 12th, 2007

    Just a quick update. My surgery today was successful though I feel like I got hit by a truck. Apparently the jagged bone end at the break has been progressively been cutting through the Platysma muscle, so it’s a really good thing I had surgery. The doctor reported that my heart and lungs were very strong so I got that going for me… which is good. Six weeks in a sling and then six more weeks of recovery which puts me at November 28th…

    September 11th – Where were you?

    September 10th, 2007

    9/11/01 – Jeanie and I were leaving a bed and breakfast in Zion, UT to head to the airport for a morning flight back to Philadelphia. As we were readying to walk out the door, we heard some commotion from the other visitors who were glued to the television. Soon after we saw the second plane hit the second tower. Our flight was obviously canceled, and we spent the day catatonicly driving around Bryce Canyon and the next 8 days stranded on the Strip in Las Vegas after our first rescheduled flight was canceled as the flight ban was extended.


    9/11/01 Outside Zion National Park – notice the flag at half mast.
    102-0266_img-500px.jpg

    Where were you?

    Ephraim

    September 10th, 2007

    A lot has happened since my last couple posts. Most notably is that we’ve taken in a foreign exchange student for the school year. Ephraim is a 17 year old exchange student from Taraba State, Nigeria. This is his first time he’s left his state, country, flown, used an overhead shower, dishwasher, electric stove, etc, etc. He’ll be staying with us all the way through May. Stay tuned for more updates. I’m sure it will be an interesting time…

    The day after we met Ephraim, we drug him up to the mountains for a camping trip over Labor Day weekend. We rented 3 small cabins at Elk Creek Campground in Grand Lake, CO just outside of Rocky Mountain National Park. In case you were wondering, yes, I did bring the recliner, nursing my broken collarbone.


    Group Picture:
    img_9897.jpg



    Ephraim:
    img_8154.jpg

    Powered by Web Design Company Plugins

    Switch to our mobile site