Results 1 to 16 of 16

Thread: Authenticating users / membership provider AND windows authentication

  1. #1

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Authenticating users / membership provider AND windows authentication

    We have only ever used the membership provider to give users access to our pages. With all the folder protection stuff and roles and so on.

    But now we have a public-facing website where both teachers and parents will be connecting from outside the network.

    The teachers already have inside-the-network domain usernames and passwords.

    How can I have the teachers log in with the same un/pw as their domain un/pw but still have them be part of the membership provider world.

    The parents do not have domain un's - so we know we have to give them membership/provider un's.

    Is it even a good idea to do what I'm asking? Is this a bad security model?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  2. #2
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    Have you ever seen Outlook Web Access? When logging in to your OWA account, it'll ask you for your domain username/password. So the point is, it's possible and commonly used. But you'll need to do a bit of work for this - you'll need to make a custom membership and roles provider that talks to ActiveDirectory.

    The good news is that, like I said, it's common. So there's sample code for this.
    http://msdn.microsoft.com/en-us/library/ms998360.aspx

  3. #3

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    Excellent - OWA was kind of what I was thinking about - I've got EXCHANGE on my SBS in the office and I use OWA when outside my network...

    I'll look at the link.

    Thanks again.

    btw - do you think we will be able to mix both the SqlMembershipProvider (for parents) and the ActiveDirectoryMembershipProvider (for teachers).

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  4. #4
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    You'll need to make a SqlAndActiveDirectoryMembershipProvider... When any of the methods are being called, such as ValidateUser, you'll need to distinguish between the two types of credentials before sending the query to AD or SQL. Then again that could be easy, the AD credentials will be networkname\something, the SQL credentials will not.

    But yes, you'll be able to combine them. You could write both providers separately, and write a third provider which in turn simply calls one of the original two based on the username.

  5. #5

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    We started trying to validate users with Active Directory and have hit a road block.

    How is the DirectoryEntry path supposed to be structured? Ours looks like :
    Code:
    LDAP://antares.local/CN=Users,DC=antares,DC=local
    With this path (and with a correct un/pw combo) we never find the user and the result is always nothing.

    Our Active Directory structure looks like this :


    When we change the string such as
    Code:
    LDAP://antares.local/CN=MyBusiness\SBSUsers\Users,DC=antares,DC=local
    We get 'there is no such object on the server'.

    We use this code to check for the user.
    Code:
        Protected Function AuthenticateUserAD(ByVal domain As String, ByVal username As String, ByVal password As String) As Boolean
            Dim domainAndUserName = domain + "\" + username
            Dim LDAPPATH As String
    
            Dim entry As New DirectoryEntry("LDAP://antares.local/CN=Users,DC=antares,DC=local", domainAndUserName, password)
            Try
                Dim obj = entry.NativeObject
                Dim search As DirectorySearcher = New DirectorySearcher(entry)
                search.Filter = "(SAMAccountName=" + username + ")"
                search.PropertiesToLoad.Add("cn")
                Dim result As SearchResult = search.FindOne
                If result Is Nothing Then
                    Return False
                Else
                    LDAPPATH = result.Path
                    Return True
                End If
    
            Catch ex As Exception
                Return False
            End Try
    
        End Function

    What are we doing wrong?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  6. #6
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    The machine that you're calling this LDAP connection string (or binding string) from - is it in the same domain as antares.local or is it outside? If it's inside the same domain, then forget the server name, skip straight to the filters, you're mentioning it in the DC attribute anyways.

    LDAP://CN=Users,DC=antares,DC=local

    But that's not important, you can still use the domain controller if you want. Your first binding string looks right...


    OK, that aside... I just noticed that I missed out on an important link in a previous post. Sorry

    http://msdn.microsoft.com/en-us/libr...pprovider.aspx

    There's a provider that already exists for AD membership... it involves configuring something called ADAM (Active Directory for App Management, I think) on your DC boxes. Have a read through. Sorry about the confusion.

  7. #7

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    Using the same connection string in the email above we used Membership.CreateUser() to create a test user with a test password. Then when we use Membership.Validate() with the test user and password it returns true. However, none of the users in the OU "MyBusiness\Users\SBSUsers" can be validated. When the test user is moved into that OU it can no longer be validated either.

    We tried using this connection string :
    Code:
    LDAP:\\antares.local\OU=MyBusiness,OU=Users,OU=SBSUsers,DC=antares,DC=local
    And it claims the container doesnt exist.

    What is wrong with the connection string?

    What does the domain (ex: DOMAIN\User) mean to the membership provider and how do we use it?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  8. #8

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    With no "CN=Users" and with attritubeMapUsername="sAMAccountName" it returns true for users in SBSUsers.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  9. #9
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    Really can't say much, that should be working.

    Wait - how are you 'using' the connection string. What is the ASP.NET application's identity? Does it start working if you change it to a privileged user?

    Throwing another link your way - http://blogs.msdn.com/gduthie/archiv...17/452905.aspx

    This guy talks about using the AD membership provider.

  10. #10

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    So we now have membership working with both SQL and ActiveDirectory, and we have a SQLRoleProvider and an ActiveDirectoryRoleProvider.

    How do we set up authorization to use both Role Providers and Membership?
    Does it know which one to use based on which one contains a [currently] valid user?
    How does it know which role provider to use?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  11. #11
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    You got it working? What was wrong, and how did you get it working?

    To do the 'switch' you're going to have to do it programmatically. Here's what I'm thinking. When the user goes to the login form, there's a dropdown they have to choose from. Parent or Teacher. (Or whatever your categories were). The value chosen then determines which provider you're going to load up.

    Start by creating yet another Membership Provider. Call it the MixedAuthenticationProvider. In each of its methods, look at the current session value (parent/teacher - you have to store that always, or in a cookie, but encrypted) and based on that, use it in each of the implemented methods. So as an example, in the mixed provider's UpdateUser method, look at the session variable, then load up the correct provider, then call, in turn, its UpdateUser method.

    vb Code:
    1. Dim actualMembershipProvider =
    2. Membership.Providers.Item("MyActiveDirectoryMembershipProvider")
    3. actualMembershipProvider.UpdateUser(...)

    Remember that both membership providers must be registered in web.config.

  12. #12

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    We took out the CN="Users" and ended up with just "LDAP://antares.local/DC=antares,DC=local". We then made two membership and role providers. The membership providers are called ActiveDirectoryMembership and SQLMembership and the role providers are called ActiveDirectoryRoles and SQLRoles.

    The mixed providers would both be the default providers, right?
    Then we would override the subs that do membership validation to check to see which membership to use and then call that memberships validation. Is ASP smart enought to do that?
    With the MixedRoles would that work with our authorization tags? ie: <deny roles="student">
    How does ASP determine the current user is a "student"? Does it ask the default role provider? Is there a specific function it uses? Like IsUserInRole and if our role provider returns true it would block them from the web page.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  13. #13

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    Mendhak,

    Here is some of our code:

    This code defines our AD and SQL Membership Providers

    Code:
       <membership defaultProvider="SqlProvider">
          
          <providers>
              <clear />
              <add
                name="SqlProvider"
                type="System.Web.Security.SqlMembershipProvider"
                connectionStringName="LocalSQLServer"
                applicationName="GradeAnywhere"
                enablePasswordRetrieval="false"
                enablePasswordReset="true"
                requiresQuestionAndAnswer="true"
                requiresUniqueEmail="true"
                passwordFormat="Hashed" />
            <add
              name="MembershipADProvider"
              type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, 
                Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
              connectionStringName="ADConnectionString"
              connectionUsername="admin" 
              connectionPassword="password"
              attributeMapUsername="sAMAccountName"/>
            
       
          </providers>
        </membership>
    And this code defines our role providers
    Code:
    <roleManager enabled="true" cacheRolesInCookie="true" 
                            defaultProvider="SqlRoleManager"
                            cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="
                            30" cookieRequireSSL="false"
                            cookieSlidingExpiration="true" 
                            createPersistentCookie="false" cookieProtection="All">
          <providers>
            <add name="SqlRoleManager"
                 type="System.Web.Security.SqlRoleProvider"
                 connectionStringName="LocalSQLServer"
                 applicationName="GradeAnywhere" />
          <add name="MyADRoleProvider"
              type="CustomRoleProvider"			connectionStringName="ADConnectionString"
    	applicationName="/"
    	connectionUsername="admin"
              connectionPassword="password" />
          </providers>
          
        </roleManager>
    And this code defines our "CustomRoleProvider" class.
    Code:
    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections
    Imports System.Collections.Generic
    Imports System.DirectoryServices
    Imports System.Web.Configuration
    Imports System.Web.Security
    
    Public Class CustomRoleProvider
        Inherits RoleProvider
    
        Dim _connectionString As String = ""
        Dim _applicationName As String = ""
        Dim _userName As String = ""
        Dim _userPassword As String = ""
    
        Public Overrides Sub Initialize(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection)
    
            _connectionString = config("connectionStringName")
    
            If String.IsNullOrEmpty(config("applicationName")) Then
                _applicationName = config("applicationName")
            End If
            If String.IsNullOrEmpty(config("connectionUsername")) Then
                _userName = config("connectionUsername")
            End If
            If String.IsNullOrEmpty(config("connectionPassword")) Then
                _userPassword = config("connectionPassword")
            End If
    
            MyBase.Initialize(name, config)
        End Sub
    
        Public Overrides Property ApplicationName() As String
            Get
                Return _applicationName
            End Get
            Set(ByVal value As String)
                _applicationName = value
            End Set
        End Property
    
        Public Overrides Sub AddUsersToRoles(ByVal usernames() As String, ByVal roleNames() As String)
    
        End Sub
    
        Public Overrides Sub CreateRole(ByVal roleName As String)
    
        End Sub
    
        Public Overrides Function DeleteRole(ByVal roleName As String, ByVal throwOnPopulatedRole As Boolean) As Boolean
    
        End Function
    
        Public Overrides Function FindUsersInRole(ByVal roleName As String, ByVal usernameToMatch As String) As String()
    
        End Function
    
        Public Overrides Function GetAllRoles() As String()
    
        End Function
    
        Public Overrides Function GetRolesForUser(ByVal username As String) As String()
    
            Dim obEntry As DirectoryEntry = New DirectoryEntry(WebConfigurationManager.ConnectionStrings(_connectionString).ConnectionString)
            Dim srch As DirectorySearcher = New DirectorySearcher(obEntry, "(sAMAccountName=" + username + ")")
            Dim res As SearchResult = srch.FindOne()
            Dim dictionary As Dictionary(Of String, String) = New Dictionary(Of String, String)
    
            If res IsNot Nothing Then
                Dim obUser As DirectoryEntry = New DirectoryEntry(res.Path)
    
                Dim rootPath As String = WebConfigurationManager.ConnectionStrings(_connectionString).ConnectionString
                rootPath = rootPath.Substring(0, rootPath.LastIndexOf("/") + 1)
    
                GetMemberships(obUser, dictionary, rootPath)
            End If
    
            Dim ary(dictionary.Count) As String
            dictionary.Values.CopyTo(ary, 0)
            Return ary
    
        End Function
    
        Private Sub GetMemberships(ByRef entry As DirectoryEntry, ByRef dictionary As Dictionary(Of String, String), ByVal rootPath As String)
    
            Dim childrenToCheck As List(Of DirectoryEntry) = New List(Of DirectoryEntry)
    
            Dim children As PropertyValueCollection = entry.Properties("memberof")
    
            For Each childDN As String In children
    
                'childDN = Mid(childDN, 1, InStr(childDN, ",") - 1)
    
                If Not (dictionary.ContainsKey(childDN)) Then
    
                    Dim obGpEntry As DirectoryEntry = New DirectoryEntry(rootPath + childDN)
                    Dim groupName As String = obGpEntry.Properties("sAMAccountName").Value.ToString()
    
                    dictionary.Add(childDN, groupName)
                    childrenToCheck.Add(obGpEntry)
    
                End If
    
            Next
    
            For Each child In childrenToCheck
                GetMemberships(child, dictionary, rootPath)
            Next
        End Sub
    
        Public Overrides Function GetUsersInRole(ByVal roleName As String) As String()
    
        End Function
    
        Public Overrides Function IsUserInRole(ByVal username As String, ByVal roleName As String) As Boolean
            Dim ary As String()
            ary = GetRolesForUser(username)
            For Each item In ary
                If roleName.ToLower = item.ToLower Then Return True
            Next
            Return False
        End Function
    
        Public Overrides Sub RemoveUsersFromRoles(ByVal usernames() As String, ByVal roleNames() As String)
    
        End Sub
    
        Public Overrides Function RoleExists(ByVal roleName As String) As Boolean
    
        End Function
    End Class
    So when we use authorization code like this :
    Code:
        <authorization>
          <deny roles="student"/>
        </authorization>
    How do the role providers or MixedRoleProvider determine whether the user is blocked?
    Is it as simple as them calling "IsUserInRole(currentuser)"?
    How does the membership keep track of whether or not there even is a current user and what that users name is?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  14. #14
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    Yes, that's right - it will call IsUserInRole, many times in fact. Everything the membership provider does (User.Identity.Name) centers around its own session variable. Any extra information that's needed is retrieved from the methods you write in those providers, such as IsUserInRole or GetRoleForUser. No session variable means no user or user has logged out.

  15. #15

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Authenticating users / membership provider AND windows authentication

    Quote Originally Posted by mendhak View Post
    ... Everything the membership provider does (User.Identity.Name) centers around its own session variable...
    This is blank for us - look how we got here

    Code:
    Imports Microsoft.VisualBasic
    
    Public Class MixedMembership
        Inherits MembershipProvider
    
    
        Public Overrides Property ApplicationName() As String
            Get
                Stop
            End Get
            Set(ByVal value As String)
                Stop
            End Set
        End Property
    
    .
    .
    .
        Public Overrides Function UnlockUser(ByVal userName As String) As Boolean
            Stop
        End Function
    
        Public Overrides Sub UpdateUser(ByVal user As System.Web.Security.MembershipUser)
            Stop
        End Sub
    
        Public Overrides Function ValidateUser(ByVal username As String, ByVal password As String) As Boolean
            If Membership.Providers("ActiveDirectoryMembershipProvider").ValidateUser(username, password) Then
                Return True
            ElseIf Membership.Providers("SQLMembershipProvider").ValidateUser(username, password) Then
                Return True
            Else
                Return False
            End If
        End Function
    End Class
    Validate user runs fine - the first IF with ActiveDirectoryMembershipProvider validates the username and password - returns TRUE like it should.

    Login control then redirects to the next page where we have this

    Code:
    Imports System.Security.Principal
    
    Partial Class ClassSelection
        Inherits System.Web.UI.Page
    
        Dim SProcinator As New SprocExecutor
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim myPrincipal As IPrincipal = Me.User
            Dim ds As Data.DataSet = SProcinator.ExecSproc("dbo.gspGetTeaNum", True, "@TeaUserName", User.Identity.Name)
    The myPrincipal stuff was just me debugging - but the point is that ME.USER is not setup

    Code:
    ?Me.User.Identity
    {System.Security.Principal.GenericIdentity}
        System.Security.Principal.GenericIdentity: {System.Security.Principal.GenericIdentity}
        AuthenticationType: ""
        IsAuthenticated: False
        Name: ""
    Why is ME.USER.IDENTITY blank????

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  16. #16
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Authenticating users / membership provider AND windows authentication

    Could be for several reasons, but the most common reasons are

    1. You're still using no authentication/anonymous authentication. Change the web.config authentication mode node to Forms.
    2. Are you remembering to set the auth cookie?
    3. http://support.microsoft.com/?id=306359

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width