Connect SharePoint 2010 Web Application to OpenLDAP

Requirements:

  1. Company does not want to use Active Directory for external (untrusted) users.  This would consume a user CAL license for each user, along with giving that user potentially more rights on our internal private network domain than wanted.
  2. Company uses other enterprise software programs that consume user authentication from a non-central user store and lacks user tracking.  Stand up a central LDAP store for these external users that are accessing these other systems and begin tracking information like phone numbers, address, expected length of access needed, etc.  This will allow IT the ability to inquire if the access is still necessary.
  3. Allow Integrated Windows Authentication for normal domain users to interact with content on the Extranet on SharePoint 2010 Server.
  4. All SharePoint web sites utilize SSL-only (not even http with alternate access mappings) and Kerberos.

Environment:

  • SharePoint Server 2010 Enterprise
    • Server: Windows Server 2008 R2 with IIS7
    • All web applications including Central Admin use SSL and Kerberos
  • OpenLDAP 2.4.23 SSL-only
    • Server: RHEL 6 Linux
    • Confirm that: "olcAllows: bind_v2" exists in the configuration.
  • OpenLDAP GUI Client is Apache Directory Studio

Implementation:

  1. Configure DNS entries for the new web URL, (example: ext.portal.com).
  2. Ensure SSL certificate is available with wildcard cert (example: *.portal.com) for the IIS bindings.  You can ignore this and the host header settings I use if you are not using SSL.
  3. Create a new web application with these settings:
    1. Use Claims Based Authentication (Important).
    2. Create new IIS web Site, call it something friendly like: ext.portal.com - 443
    3. Port: 443.
    4. Host Header: ext.portal.com.
    5. Leave Path alone.
    6. Allow Anonymous: No.
    7. Use Secure Sockets Layer: Yes.  (Can skip this if not using SSL, just don't use port 443)
    8. Enable Windows Authentication.  Choose NTLM, or in my case I use Kerberos.
      1. For Kerberos: Register the Service Principal names on a domain server with domain administrator credentials.
      2. Open Command prompt as Administrator.
      3. Run: setspn -s HTTP/ext.portal.com domain\app.pool.account (change to suit yours).
      4. Run: setspn -s HTTP/ext.portal.com:443 domain\app.pool.account (If SSL, else :80).
    9. Enable Forms Based Authentication (FBA)
      1. Membership Provider Name: OpenLDAPMember (Must match all entries in web.config(s).
      2. Role Manager Name: OpenLDAPRole (Must match all entries in web.config(s).
      3. Note: Membership = Users, Role=Groups. Get it?
    10. Public Url: https://ext.portal.com (This should match your settings)
    11. Create a new application pool, name it something friendly: ext.portal.com - AppPool - 443 and set the account (This account should be what you registered the SPNs under if using Kerberos).
    12. Enter a good Content Database name consistent with your database naming conventions.
    13. If you use database mirroring enter the failover server.
    14. Adjust Service Application settings if you wish to restrict what Service Application features your Extranet users should be able to consume.  I have heard that some Forms-Based SharePoint sites have issues with things like Excel Services.  I suggest allowing all on a test or development server and experiment to find what the impact of certain applications is.  Then create a custom connection group for the Extranet for production system(s).
    15. Click Okay.
  4. Make sure you understand the user and group schema in your OpenLDAP.  I added a number of attributes to develop what I consider a starting baseline for a user account.  I am sure we will add more later.  The biggest reason I failed for days to authenticate to my new web application with a forms-based user in OpenLDAP, is because I was using the wrong dnAttribute in my web.config settings.  I was pointing to "dn", when for OpenLDAP I needed to point to "entryDN".  I only found this value by fetching Operational Attributes in Apache Directory Studio.
  5. Edit Central Admin web.config.  This can be a hard location to find, but if you use IIS Manager to right-click on the site and choose "Explore" you will always find web.config easily.  Important: Always copy and paste a backup first, then edit.  Replace the settings for roleManager, membership, and PeoplePickerWildcards already in the file.(see settings below).
  6. Edit the new Claims-Based web site web.config in the same manner as you edited the Central Admin in step 5.  Note that their are multiple providers listed in this file because it inherits some for the Windows Authentication settings, but there are already there for you. (see settings below).
  7. Edit the Security Token Service web.config.  Find this in IIS Manager by opening the SharePoint Web Services site and right-clicking on SecurityTokenServiceApplication and choosing explore to find that web.config file.  In this file there is no section for roleManager or membership providers.  You need to add a section at the very end of the file just before the </configuration> tag and after the closing </system.net> tag. (see settings below).
  8. Restart IIS.  Command Prompt, iisreset<enter>.
  9. Test the new website with Windows Authentication with an account that has Full Control.  Go into Permissions, Grant Permissions, select the address book icon, Click on All Users on the left, and try to add All Users (OpenLDAPMember). Grant them whatever level of permissions they need.  This will allow you to login with username and password of a test account from your OpenLDAP server.
  10. Click Sign in as Different User.  Select Forms Authentication, login with test account.
  11. Next I will work on creating a custom login.aspx page for this site.

Central Admin web.config settings (Company details anonymous):

<roleManager enabled="false">
    <providers>
      <add name="OpenLDAPRole" type="Microsoft.Office.Server.Security.LDAPRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.portal.com" port="636" useSSL="true" connectionUsername="cn=ldap-admin,dc=portal,dc=com" connectionPassword="password" groupContainer="ou=Groups,ou=ExternalUsers,dc=portal,dc=com" groupNameAttribute="cn" groupMemberAttribute="uniqueMember" groupFilter="(objectClass=groupOfUniqueNames)" scope="Subtree" />
    </providers>
</roleManager>
<membership>
    <providers>
<add name="OpenLDAPMember" type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.portal.com" port="389" useSSL="false" connectionUsername="cn=ldap-admin,dc=portal,dc=com" connectionPassword="password" userDNAttribute="entryDN" userNameAttribute="cn" userContainer="ou=Users,ou=ExternalUsers,dc=portal,dc=com" userObjectClass="inetOrgPerson" userFilter="(objectClass=inetOrgPerson)" scope="Subtree" otherRequiredUserAttributes="uid,cn" />
    </providers>
</membership>

<PeoplePickerWildcards>
    <clear />
    <add key="AspNetSqlMembershipProvider" value="%" />
    <add key="OpenLDAPMember" value="*" />
    <add key="OpenLDAPRole" value="*" />
</PeoplePickerWildcards>

Forms-Based Claims Site web.config settings:

    <membership defaultProvider="i">
      <providers>
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="OpenLDAPMember" type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.issinc.com" port="389" useSSL="false" connectionUsername="cn=ldap-admin,dc=issinc,dc=com" connectionPassword="0p3nLD@P" userDNAttribute="entryDN" userNameAttribute="cn" userContainer="ou=Users,ou=ExternalUsers,dc=issinc,dc=com" userObjectClass="inetOrgPerson" userFilter="(objectClass=inetOrgPerson)" scope="Subtree" otherRequiredUserAttributes="uid,cn" />
      </providers>
    </membership>
    <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="true">
      <providers>
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="OpenLDAPRole" type="Microsoft.Office.Server.Security.LDAPRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.issinc.com" port="389" useSSL="false" connectionUsername="cn=ldap-admin,dc=issinc,dc=com" connectionPassword="0p3nLD@P" groupContainer="ou=Groups,ou=ExternalUsers,dc=issinc,dc=com" groupNameAttribute="cn" groupMemberAttribute="uniqueMember" groupFilter="(objectClass=groupOfUniqueNames)" scope="Subtree" />
      </providers>
    </roleManager>

    <PeoplePickerWildcards>
      <clear />
      <add key="AspNetSqlMembershipProvider" value="%" />
 <add key="OpenLDAPMember" value="*" />
      <add key="OpenLDAPRole" value="*" />
    </PeoplePickerWildcards>

SecurityTokenServiceApplication web.config settings:

  <system.web>
    <membership>
      <providers>
        <add name="OpenLDAPMember" type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.issinc.com" port="389" useSSL="false" connectionUsername="cn=ldap-admin,dc=issinc,dc=com" connectionPassword="0p3nLD@P" userDNAttribute="entryDN" userNameAttribute="cn" userContainer="ou=Users,ou=ExternalUsers,dc=issinc,dc=com" userObjectClass="inetOrgPerson" userFilter="(objectClass=inetOrgPerson)" scope="Subtree" otherRequiredUserAttributes="uid,cn" />
      </providers>
    </membership>
<roleManager enabled="true">
 <providers>
   <add name="OpenLDAPRole" type="Microsoft.Office.Server.Security.LDAPRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ldap.issinc.com" port="389" useSSL="false" connectionUsername="cn=ldap-admin,dc=issinc,dc=com" connectionPassword="0p3nLD@P" groupContainer="ou=Groups,ou=ExternalUsers,dc=issinc,dc=com" groupNameAttribute="cn" groupMemberAttribute="uniqueMember" groupFilter="(objectClass=groupOfUniqueNames)" scope="Subtree" />
 </providers>
</roleManager>
  </system.web>
</configuration>

Comments

Popular posts from this blog

SharePoint Designer 2013 Approval Workflow with Comments

Change SharePoint server hostname and Web Application Names

SharePoint Search - Content Processing Pipeline Failed to Process the Item