CodeSmith Community
Your Code. Your Way. Faster!

MembershipProvider for .netTiers

Latest post 09-18-2008 10:42 AM by peelay. 31 replies.
  • 08-20-2006 10:06 AM

    • charlie
    • Top 75 Contributor
    • Joined on 05-06-2006
    • Omaha, Nebraska, USA
    • Posts 60
    • Points 1,605

    MembershipProvider for .netTiers

    I have been working on a custom MembershipProvider for .netTiers. I got really frustrated with using the existing SQL MembershipProvider, because the standard implementation makes it very difficult to use databinding with the GridView, FormView, DetailsView, etc. The problem is a) there is no MembershipDataSource control that allows a declarative databinding approach, and b) when you try to hook it up programmatically, i.e.,

            MembershipUserCollection users = Membership.GetAllUsers();
            GridView1.DataSource = users;
            DataBind();


    it doesn't work anyway, because the MembershipUser object doesn't implement a default constructor, and for whatever reason, the GridView and the other various databinding classes require one in certain situations, like when adding a new row to the grid.

    Another problem with the default Membership implementation is that I'm stuck with the naming conventions and column types supplied by Microsoft. For example, the primary key for the aspnet_Users table is a GUID, whereas I generally use INTs throughout my database.

    And of course the other irritating thing is having to mix different providers that aren't built to work together. When I use the Membership API, I'm using one API for my user management, and .netTiers for everything else. So when I build my user management pages, I can't use the typed data sources and all the other goodies that come with .netTiers.

    So I decided to build a custom MembershipProvider that works with the .netTiers classes. So far, I've built a few classes designed to be specific to the project I'm currently working on. My goal is to eventually create templates to generate these custom classes. In the test implementation I've built so far, I've got these two classes:

    EntityMembershipUser
    EntityMembershipProvider


    The first class overrides the MembershipUser class, changing all properties to use properties from my custom G4LUser entity (which is generated by .netTiers and uses a custom table in my database). In addition to the standard MembershipUser properties, it implements a UserEntity property, which returns the underlying .netTiers entity. So for example, you can do something like this:

        MembershipUser member = Membership.GetUser( "username" );
        G4LUser user = ((EntityMembershipUser) member).UserEntity;


    In this case, my .netTiers user entity is called G4LUser. I can obtain an instance of the entity by going through the UserEntity property of the EntityMembershipUser class.

    The second class, EntityMembershpProvider uses the .netTiers generated DAL to retrieve and update users. Any class that returns MembershipUser actually returns a EntityMembershipUser, so that the underlying entity can be retreived -- see the above code example.

    ANYWAY, the reason I'm writing all this is because I wondered if this would be something that you guys would be interested in seeing included in the .netTiers project. If you think it would be, I would appreciate feedback from everyone who might find this useful. I'd also like to talk about namespaces (currently I'm using <WebNamespace>.Security to match Microsoft's System.Web.Security) and naming conventions. I may eventually need some help with converting my code into templates, although I'm working on that now and I think I've pretty much got it. Also, if this is something that people would be interested in, I'll probably eventually extend the project to include a RoleProvider and ProfileProvider.

    Thoughts?
    • Post Points: 80
  • 08-20-2006 6:51 PM In reply to

    • charlie
    • Top 75 Contributor
    • Joined on 05-06-2006
    • Omaha, Nebraska, USA
    • Posts 60
    • Points 1,605
    Alright, I hope there is interest in this Wink [;)], because I've gone ahead and converted my code into templates. I've attached a zip file that has the .netTiers templates with my changes included. I've gone ahead and included the full set of templates for ease of generation. My changes were made on a copy of the 2.0 Beta 2 release, so anything that works for Beta 2 will still work with this copy, in addition to having some extra options to generate a Web.Security library.

    Documentation to follow.
    • Post Points: 35
  • 08-20-2006 7:12 PM In reply to

    Re: MembershipProvider for .netTiers

    Awesome charlie!! Thanks for your interest in contributing.  This is one of those areas that will be a great feature to add!  And since it's a generation time option, it will be great to not force devs to use this or not.  I would really like to see the profile and role providers as well.  We can have a discussion on this offline.

    Robert Hinojosa
    -------------------------------------
    Member of the Codesmith Tools, .netTiers, teams
    http://www.nettiers.com
    -------------------------------------
    • Post Points: 5
  • 08-20-2006 7:23 PM In reply to

    • charlie
    • Top 75 Contributor
    • Joined on 05-06-2006
    • Omaha, Nebraska, USA
    • Posts 60
    • Points 1,605

    Re: MembershipProvider for .netTiers

    As promised, here's some preliminary documentation. I'll update this as I get feedback and make changes to the EntityMembershipProvider.

    First, an overview. As I mentioned in my first post, I got tired of the limitiations I faced when working with the ASP.NET Membership controls. I loved that so much of the work was done for me, but it really felt like getting the Microsoft tables to work with my .netTiers tables required way too much effort. It was basically like working with two different types of data providers -- the Membership providers, and .netTiers. My goal with this project was to combine the two, so you can have all the advantages of the Membership controls (like the Login, LoginView, LoginName, and ChangePassword controls) without having to sacrafice the flexibility of using the .netTiers entites and web library.

    Right now, there are some limitations built in to the EntityMembershipProvider:

    1. It only supports entities generated from tables, not from views.
    2. The primary key of your Users table must be either a UniqueIdentifier (a GUID) or an Int that auto-increments.
    3. Table structure must have, at a minimum, the columns required by MembershipUser. More on this in a moment.
    4. All extra columns must allow nulls.
    5. Due to inheriting from the MembershipUser entity, Microsoft's built in ASP.NET Configuration Tool doesn't work. That sucks, but so far I have been unable to find a way around it.

    But if you can live with that, the EntityMembershipProvider should work well.

    To configure it, there are a few things that need to happen. First, you need to create a table that contains, at a minimum, the columns required by MembershipUser. To get a jump start, you can use this table:

    CREATE TABLE Users
    (
        PKID INT IDENTITY(1,1) NOT NULL,
        Username varchar(255) NOT NULL,
        ApplicationName varchar(255) NOT NULL,
        Email varchar(128) NOT NULL,
        Comment varchar(255) NULL,
        Password varchar(128) NOT NULL,
        PasswordQuestion varchar(255) NULL,
        PasswordAnswer varchar(255) NULL,
        IsApproved bit NOT NULL DEFAULT(0),
        LastActivityDate datetime NULL,
        LastLoginDate datetime NULL,
        LastPasswordChangedDate datetime NULL,
        CreationDate datetime NOT NULL,
        IsLockedOut bit NOT NULL DEFAULT(0),
        LastLockoutDate datetime NULL,
        FailedPasswordAttemptCount int NULL,
        FailedPasswordAttemptWindowStart bit NOT NULL DEFAULT(0),
        FailedPasswordAnswerAttemptCount int NULL,
        FailedPasswordAnswerAttemptWindowStart datetime NULL
        PRIMARY KEY (PKID)
    )

    You can add any number of columns you want to this table, as long as they allow null values.

    Next, be sure that the SourceTables property includes the user table. Then set the EntityMembershipUserPKCol property to the primary key column on the Users table (in the table above, it's PKID). At this point, you're ready to generate. You should get an extra library, <RootNamespace>.Web.Security.

    Finally, you must add a reference to the new library to your project and update your Web.config file to use the EntityMembershipProvider:

        <system.web>
            <membership defaultProvider="EntityMembershipProvider"
                userIsOnlineTimeWindow="15">
                <providers>
                    <add name="EntityMembershipProvider"
    type="<RootNamespace>.Web.Security.EntityMembershipProvider"
                        enablePasswordRetrieval="true"
                        enablePasswordReset="true"
                        requiresQuestionAndAnswer="false"
                        applicationName="/"
                        requiresUniqueEmail="false"
                        passwordFormat="Hashed"
                        maxInvalidPasswordAttempts="15"
                        minRequiredPasswordLength="4"
                        minRequiredNonalphanumericCharacters="0"
                        passwordAttemptWindow="10"
                        passwordStrengthRegularExpression="" />
                </providers>
            </membership>
     

    You can set the options listed here to the values required by your application.

    And that's it! Your application should be running using the EntityMembershipProvider.

    There's also an option to allow you to have column names that are different from the table defined above, but I'm gonna break that into its own post.
    • Post Points: 5
  • 08-20-2006 7:43 PM In reply to

    • charlie
    • Top 75 Contributor
    • Joined on 05-06-2006
    • Omaha, Nebraska, USA
    • Posts 60
    • Points 1,605

    Re: MembershipProvider for .netTiers

    As I mentioned in the last post, although the User table you create must include all the columns required for by the MembershipUser object, you have the option to name those columns anything you want.

    If your column names are the same as the property names of the MembershipUser object, everything will Just Work without any extra effort. But there are times that isn't always possible, and there are other times you simply don't care for the default schema. In that case, you can make a text file that maps MembershipUser property names to User table column names. (For those who are familiar with it, it acts similar to the AliasFilePath property.)

    The map file expects one mapping per line. Each line should be in in the format:

    MembershipUserProperty:TableColumnName

    It isn't necessary to include every property in the file. If you include something that isn't a valid MembershipUserProperty, or something that isn't a valid column name for the table you have chosen via  your selection of EntityMembershipUserPKCol, it will just ignore that line.

    So you don't have to look up the property names that are required, here is a listing of every valid MembershipUser property, mapped to a column of the same name (in other words, using this as your file would give you the same behavior as not including a mapping file at all):

    ApplicationName:ApplicationName
    Comment:Comment
    CreationDate:CreationDate
    Email:Email
    FailedPasswordAttemptCount:FailedPasswordAttemptCount
    FailedPasswordAttemptWindowStart:FailedPasswordAttemptWindowStart
    FailedPasswordAnswerAttemptCount:FailedPasswordAnswerAttemptCount
    FailedPasswordAnswerAttemptWindowStart:FailedPasswordAnswerAttemptWindowStart
    IsApproved:IsApproved
    IsLockedOut:IsLockedOut
    LastActivityDate:LastActivityDate
    LastLockoutDate:LastLockoutDate
    LastLoginDate:LastLoginDate
    LastPasswordChangedDate:LastPasswordChangedDate
    PasswordQuestion:PasswordQuestion
    PasswordAnswer:PasswordAnswer
    ProviderUserKey:ProviderUserKey
    UserName:UserName

    If you'd like to, for example, change your primary key column name to "UserID", change the second to last line to read:

    ProviderUserKey:UserID

    MembershipUserMapFile property to point to the text file that contains the mappings, and you're ready to generate with mapped column names.

    That's it! I believe that covers all the features in my new template set. Let me know if you have any questions about it, or any ideas for improvement.
    • Post Points: 35
  • 05-03-2007 11:32 AM In reply to

    • asmussen
    • Top 200 Contributor
    • Joined on 11-12-2006
    • Posts 21
    • Points 675

    Re: MembershipProvider for .netTiers

    Has anyone updated this for .netteirs 2.01?

     Thanks, Justin.
     

    • Post Points: 35
  • 05-03-2007 12:55 PM In reply to

    • charlie
    • Top 75 Contributor
    • Joined on 05-06-2006
    • Omaha, Nebraska, USA
    • Posts 60
    • Points 1,605

    Re: MembershipProvider for .netTiers

    No, but getting this rewritten and integrated into NetTiers has been on the proverbial Spare Time To Do List for about six months. Unfortunately, things aren't showing any signs of slowing down. I need to block out a week and get it done. Since there is interest, I'll try to make this a higher priority in the near future.
    • Post Points: 35
  • 05-03-2007 1:07 PM In reply to

    • asmussen
    • Top 200 Contributor
    • Joined on 11-12-2006
    • Posts 21
    • Points 675

    Re: MembershipProvider for .netTiers

    I was actually able to sort of do an artificial upgrade by doing a "diff and combine" in notepad++ but if I choose to generate web services it won't run.

    Has there been any talk of including this in the next version of .NetTiers?


    This is very important!!!

    P.S.

    What is every one else using? Is there an alternative membership API for .nettiers?

    • Post Points: 35
  • 10-24-2007 11:59 AM In reply to

    • Grier
    • Not Ranked
    • Joined on 02-08-2007
    • Posts 6
    • Points 156

    Re: MembershipProvider for .netTiers

     Hey Guys,

     Was any progress made on this... I feel like this would be a HUGE addition to netTiers as well.

     

    Thanks for the update!

    • Post Points: 35
  • 10-24-2007 4:09 PM In reply to

    • Faulcon
    • Top 150 Contributor
    • Joined on 12-12-2005
    • Posts 32
    • Points 1,040

    Re: MembershipProvider for .netTiers

    Would this MembershipProvider allow me to hook into and use Active Directory users and groups?

     Mark Faulcon

    • Post Points: 5
  • 02-07-2008 12:14 PM In reply to

    Re: MembershipProvider for .netTiers

    This ought to be added to .netTiers.  Right now, I am limping along with MS's solution.  I would prefer something that works with the framework.  We could have the option to generate tables as well.

    • Post Points: 35
  • 02-11-2008 10:55 AM In reply to

    • GRAW
    • Top 25 Contributor
    • Joined on 06-23-2006
    • Posts 157
    • Points 4,560

    Re: MembershipProvider for .netTiers

    Is there any progress on this? .. it looks very interesting...

    We use the membership provider in a WinForms environment and we're kind of struggling with it (we also need some additional functionalities), and this sounds really good.  We might even be able to contribute to this effort, if any help is needed.

     

    GRAW 

    "Small is the number of them that see with their own eyes, and feel with their own hearts" Albert Einstein
    • Post Points: 35
  • 04-03-2008 3:04 AM In reply to

    • brcvogt
    • Top 75 Contributor
    • Joined on 02-21-2007
    • South Africa
    • Posts 61
    • Points 1,445

    Re: MembershipProvider for .netTiers

    GRAW,

    Have you any success on using the membership provider?  I want to use it in my app, but would like to know if there is anything that I could use.  My app needs membership, roles and profiles added.

    Any help/Advice would be appreciated!

    Regards,
    Brendan

    • Post Points: 65
  • 04-03-2008 12:26 PM In reply to

    • CitizenBane
    • Top 50 Contributor
    • Joined on 10-30-2007
    • Grand Rapids, MI
    • Posts 94
    • Points 1,740

    Re: MembershipProvider for .netTiers

    I want to chime in too and ask if anyone has anything functional going with this. 

    VS2008 now has client application services.  By that, I mean that it can enable our windows-based apps to use the ASP.NET login (authentication), roles, and profile (settings) services.  I think this is the perfect time to add the custom NetTiers membership, role, and profile providers.

    -CB

    I'm outside ur box, shiftin' ur paradigm.
    • Post Points: 5
  • 04-03-2008 1:09 PM In reply to

    Re: MembershipProvider for .netTiers

    I have been rolling my own providers.  The problem is that most legacy apps have their own structure for managing users, groups, and security.  Unless we identify very granular points of contact in the database, it would not be feasable to write a script to construct security.  If you dictate the data structure, you just have what MS has already implemented.

     I will say that implementing custom providers using .netTiers is infinitely easier than anything else.

    Perhaps we could implement the providers at a level of abstraction that we would only need to point it to the appropriate services in netTiers.  But I'm not seeing that right now.

    • Post Points: 35
Page 1 of 3 (32 items) 1 2 3 Next > | RSS
Copyright © 2008 CodeSmith Tools, LLC
Powered by Community Server (Commercial Edition), by Telligent Systems