Saturday, April 21, 2012

Quebec SharePoint Summit 2012 - Debriefing

Le chateau Frontenac by night (Gilles Pommier)


Hi,
the Quebec SharePoint Summit has finished on last wednesday. It was an extremely enriching experience.

I am now starting the publishing of several posts based on what I have demonstrated during the two conferences I gave at the summit.
As the language spoken at the conference was french, and in order to serve the conference participants first in their laguage, I will first publish the posts in french within the french version of MOSS-HOW-TO : "MOSS Comment ...".

But first of all... In one of the two conferences, I have demonstrated how to do SharePoint publishing with the team sites of SharePoint Foundation.
As an example, I made a real SharePoint web facing site that was a copy of the SharePoint Summit site (that is unfortunately not made with SharePoint (but more for money reasons I learned)).

Some of the participants wanted to have the source code of the project. I promised to provide them with it, so here it is (if you don't see the link you are probably using Google Chrome... sorry, switch to IE or FF):


I stored a complete package in my SkyDrive. You will find enclosed :

The backUp file for the site collection --> sharepointsummit-6.bak

The .wsp file for deployment in the farm solution store --> MC.SpSummit_V4.0.0.0.wsp

 The source code of the original project for Visual Studio 2008 --> MC.SpSummit.Internet-sources-2012-04-20.zip

Here
is a quick manual for restoring the site :

1 - Create a Web Application within a SharePoint Farm.

1.2 - choose the 80 port

1.3 - specify this host header : sharepointsummit-ntlm

2 - create a site collection based on the team site template in english.
2.1 - Call it "Accueil"

3 - Modify the hosts file of your machine in order the url http://sharepointsummit-ntml be recognised by IIS.

3.1 - Test the url. You should display a normal english team site called Accueil by calling this Url at this step of the installation
(if there is a problem of authentification followed by an access denied, refer to http://support.microsoft.com/kb/896861)

4 - Using administrator permissions for the new site, grant access to the site for anonymous users.

5 - Modify the bindings of your IIS site correponding to the web application and add the following Url :

http://sharepointsummit.org

5.1 - Modify the hosts file in order to be able to access the IIS site with this Url.
5.2 - Test it !

6 - Add the wsp file to the solution store
6.1 - deploy the solution to
the sharepointsummit-ntlm web apllication

7 - restore the .bak file to the site collection

stsadm -o restore -url http://sharepointsummit-ntlm -filename yourPath/sharepointsummit-6.bak -overwrite

Don't forget the overwrite instruction since there is already a site collection at this Url...

8 - test the 2 Urls :

http://sharepointsummit-ntlm/SitePages/Home.aspx

http://sharepointsummit.org/SitePages/Home.aspx

It should work...

If you have any trouble, post a comment on this post...

Enjoy !!!

 

 

Tuesday, February 28, 2012

Creating a virtual machine with an LDAP authentification for SharePoint 2007

Introduction
Among the best practices to succed in fast developing good solutions for SharePoint is the virtualized environments. The closest you will be to the client production environment within your virtual machines, the best chances you will have to provide your client with a reliable solution in a quick delivery time.
Assume you have to deliver a solution requiring a form based authentication using LDAP, you sure will want to have a virtual machine with an LDAP and SharePoint on it.
This is what we are going to build in this tutorial. We will use a SharePoint farm on a single virtual machine and for the LDAP we will use Open LDAP
1 - Step 1 building the SharePoint 2007 virtual machine
The purpose of this post is  not to explain how to mount a SharePoint 2007 virtual machine.
I have already published a post on the topic, and there is more complete ones you can examine. So assume you have a virtual machine with SharePoint 2007 properly installed.
2 - Step 2 Intstalling open LDAP on the virtual machine.
I have stored on skydrive a complete package of the softwares and file you need for this tutorial.


Download the package.
In this package you will find the following items :
  • openldap-for-windows.msi
    The redistribuable package of open LDAP for windows

  • ldapbrowser26.msi
    The redistribuable package of the free LDAP browser from Softerra

  • inetorgperson.ldif
    A file that will be used to create the first LDAP account

In order to install OPEN LDAP on the virtual machinne double click  openldap-for-windows.msi. Click next on the dialogs, letting the default values untill you reach the additional settings dialog. Don't change anything neither, but notice that your machine name will be retrieved by the installation software, and carefully note the Open LDAP port number : 3899
Then click next on the other dialogs to start the installation. We are now going to use a browser to check if the installation was successfull
3 - Step 3 Browsing the LDAP server
 In order to browse the LDAP directory you are going to install the Softerra browser, so this time, double click the ldapbrowser26.msi, and follow installation process untill obtaining this final screen :
Once the Softera browser is installed, start it and we are going to create a new profile in order to test the LDAP server connection. Right click the Softerra LDAP "Browser root" node in the Scope Pane and start the new profile creation
Then, give your profile a name (I personally used the name of my virtual machine)
Now, very important, for the Host field, take the computer name of your virtual machine, in my case VMLDAP-003
And for the port, if you used the default value of the Open LDAP redistribution package for windows, it is 3899.
 Click Next. The software will prompt that base DN is not specified and ask "continue anyway". Click yes on this message. Then you will be prompted for the User DN and Password.
Where could be this information ? Actually, it is in the Open LDAP configuration file. So locate this file. It should be:
 C:\Program Files\OpenLDAP\slapd.conf

and open it with notepad
you will find these lines within the file:
rootdn  "cn=Manager,dc=maxcrc,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw  secret

This is the LDAP admin account cn=Manager,dc=maxcrc,dc=com and its password, secret so just type them in the LDAP Browser dialog:
Let the next screen default values and click finish. You will be prompted for the password again, so type it again and you should obtain this screen indication that your LDAP server is working properly:
4 - Step 4 Creating a first user account within the LDAP
We are now going to create the first account within the LDAP. This account will be used later to authenticate within SharePoint 2007.
We will use the last file of the downloaded package: inetorgperson.ldif. Go back to the OpenLDAP directory and create a ldif folder, then copy the inetorgperson.ldif file and paste it in the ldif repository.
 C:\Program Files\OpenLDAP\ldif\inetorgperson.ldif
Now open a command prompt,
locate ldapmodify.exe
C:\Program Files\OpenLDAP\ClientTools\ldapmodify.exe
and drag and drop the .exe in the command prompt:
then, in the command prompt type a space and paste this line after having replaced VMLDAP-003 by your machine name:
 -a -h VMLDAP-003 -p 3899 -D "cn=Manager,dc=maxcrc,dc=com" -w secret -f "C:\Program Files\OpenLDAP\ldif\inetorgperson.ldif"
in order to obtain this screen. The command is starting as soon as the paste operation is done...
You will notice on the screen that the ou people has been added and within the ou, the first account for the user Robert Smith.
Now if we go back in the Softerra 2.6 browser, we notice we can browse the people ou and also the Robert Smith account.
Notice we can also see the user password (rJsmitH) that will be useful later to authenticate within SharePoint 2007
Now all the work regarding the LDAP server is done. We are now going to work with SharePoint 2007
5 - Step 5 Creating the NTLM web application  for the LDAP based permissions 
For the LDAP authentication we need a specific web application because the form based authentication will be processed by an IIS web site and the LDAP connection reference will be stored within the web application web.config.
Actually, we need two IIS web sites.
The first IIS web site is the one corresponding to the web application. The web application will be accessed in NTLM mode.
This will allow administrator and power user to manage content and permissions using NTLM accounts (AD or local accounts).

Then we will extend this web application for the LDAP authentication.
This will create a second IIS web site that will be used for the form based authentication using LDAP accounts.
All this seems to be a bit confusing if you are not used to, but don't worry, we will proceed step by step and all will be clearer as long as we perform required operations...
So first let us create the web application.
Open the SharePoint Central Administration.
Click the Application Management tab.
Then, click the first link of the first section: Create or extend Web Application.
On the displayed dialog, click "Create a new Web Application"
Now I want to show you how to be as close as possible to a real production environment, so we are going to use the 80 port and an host header.
Assume the web application is used in real life for managing content (ECM) for the contoso company...

So here are the parameters to be typed:

 Create a new IIS web site - description: Web Application ECM NTLM
Create a new IIS web site - description: Web Application ECM NTLM
Port: 80
Host Header: myECM.ntlm.contoso.com
(you will notice that the path and the Url will be changed automatically based on the host header)
for the application pool, if you plan to dedicate one application pool to this web application you should call it:
SharePoint myECM.contoso.com
Because we don't need to make the distinction between NTLM and Form Based Authentication for the application pool since the both IIS web sites (the one for NTLM and the one for FBA LDAP) will use it. But if you plan to use the application pool for other web applications of your contoso company, you should call it:
SharePoint contoso.com
Because it should be used by other Contoso web application and not only by the ECM one...
Application pool user name: SPS_myECM
You should have created a dedicated service account for the application pool process.
Just create an account (AD or local) with a password that never expires (it is diffferent for SharePoint 2010).
Don't worry with permissions, the web application creation job will set all the required permissions automatically at the web application creation time.
Database Name and Authentication - database name: WSS_Content_MyECM
Because the Web Application has its own database dedicated....


Here are the summarized screen shots :
Here is the screenshot when the Web Application is created
Then we create the site collection. I chose a team site template since it is an ECM application...
Here is the screenshot after the site collection has been created
6 - Step 6 Accessing the NTLM web application
For accessing the new site collection from your local machine, first we have to modify the hosts file of the machine since we have specified an Host Header.
So, open this file with the notepad
C:\WINDOWS\system32\drivers\etc\hosts
and add this line
127.0.0.1                 myecm.ntlm.contoso.com
now try to access the site collection. You are prompted for credential and finaly you get an 401 error access denied. Hum.... Don't worry it is perfectly normal....
Now, let us do another test.
Minimize you virtual machine and switch to your host machine (the computer that is running the virtual machine), and do the same, modify the hosts file of your host computer...
Sometimes it is working with the virtual machine name. If it is not working, get the virtual machine IP by typing IPCONFIG in a command prompt within your virtual machine, or doing a ping of the virtual machine using its name from your host computer
and try to connect to your site collection from your host computer. Yes it is possible and leads to many oportunities like using two different versions of IE, using the Office applications of your host machine and so on !!!!
It does work !!!
Hum, why is it working from the host computer and we get an access denied from the local machine ?
It is because we need to specify host name on the local machine or disable the loopback check.
See this Microsoft kb entry
When performed one of the two described methods, it is working locally.
7 - Step 7 Extending the Web application for LDAP Authentication
Now is the time to extend the existing web application in order to create an IIS web site for the authentication using LDAP accounts.
Go back to the central administration.
Click the Application Management tab.
Then, click the first link of the first section: Create or extend Web Application.
On the displayed dialog, this time, click "Extend an existing Web Application"
Use the Web Application drop down list to choose the Web Application ECM NTLM previusly created
Here are the parameters and the screenshot
Create a new IIS web site - description: Web Application ECM LDAP
Port: 80
Host Header: myECM.ldap.contoso.com
Zone: Intranet
Once the web application is extended you can check the result:
in IIS:
in SharePoint Central Administration Alternate Access Mapping:
8 - Step 8 Specifying Authentication provider
Now go back to the SharePoint Central administration and under the Application Security section click the Authentication providers link
then click the Intranet link and in the next page select the Form radio button. The page is refreshing and the new interface let you type the membership provider name. Type
LdapMembershipProvider

in order to obtain this screen:
 The membership provider is used for individual permissions and the role provider to grant permissions to a group of user. In this tutorial we won't demonstrate the role provider but only the membership provider. So once the membershipprovider is specified, click OK to save the settings and close the page.
9 - Step 9 Modifying the web.config of the NTLM Web Application
Now, we have to modify the web.config files of the two web sites. So first, open the web.config of the "Web Application ECM NTLM" web site and locate the end of the system.web main section. You can use this trick: look for the machineKey tag...
Just below the machineKey tag paste this:
      <membership defaultProvider="LdapMembershipProvider">
          <providers>
              <add
              name="LdapMembershipProvider"
              type="Microsoft.Office.Server.Security.LDAPMembershipProvider, Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C"
              server="VMLDAP-003"
              port="3899"
              useSSL="false"
              connectionUsername="cn=Manager,dc=maxcrc,dc=com"
              connectionPassword= "secret"
              userNameAttribute="uid"
              userContainer="ou=people,dc=maxcrc,dc=com"
              userFilter="(objectClass=*)"
              scope="Subtree"/>
          </providers>
      </membership>
  </system.web>

Don't forget to replace VMLDAP-003 by your machine name...
Now we should be able to give permission to the LDAP unique user Robert Smith.
So open the NTLM web site and try to grant robert smith the member permission for the site by using its ldap uid.
If you type the uid rjsmith in the people picker and click the check names icon it does work.
SharePoint connect the LDAP server and retrieve the rjsmith account.
Once the account is retrieved, the typed uid become underlined and if you roll over the uid with the mouse pointer you will see the membership provider name appear in a tool tip.
So, click ok in order to actually grant this account the member permisions for the site. You will notice that the account is now referenced within SharePoint as a user of the member of the site.
9 - Step 9 Modifying the web.config of the LDAP Web Application and testing LDAP authentication
Now modify the web.config of the "Web Application ECM LDAP" web site in exactly the same way we did for the NTLM one before.
Then browse to the LDAP site using the host header. (of course you have modify the hosts file of the machine before).

You will be prompted for a Form Based Authentication within the OOTB SharePoint 2007 login page.
and if you provide the page with the required credentials:
rjsmith
rJsmitH

You will be authentified as Robert Smith and be able to contribute to the site.
Very well done !

Tuesday, November 1, 2011

Creating a Wiki Page template For SharePoint 2010 Foundation

Introduction

As I have ever written several time in my previous posts, one of the severe limitation of SharePoint Foundation is that the Wiki Pages are based on a single template wkpstd.aspx located at

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\DocumentTemplates

If you try to add a wiki page programmatically to a wiki page library of a SharePoint Foundation team site and you want it to be ghosted you must use the method SPFileCollection.Add with this signature :

 Add(String, SPTemplateFileType)

And pass the reference of the wiki page template wkpstd.aspx to the SPTemplate parameter. If you use any other signature, you will be able to add a wikipage, but it will be unghosted.

I am now going to show you a very amazing workaround to use another template than the wkpstd.aspx one and will process in  two steps. First I will demonstrate it so as you can easily understand its principle then I will provide a programmatic way of doing it.

Demonstration

Start creating your new template by duplicating the wkpstd.aspx and rename it wkpcustom.aspx, then perform a little operation of customization in order each page based on this new template can tell its name :

In the page directive section add the namespace System.Diagnostics because the wiki pages will tell their nam in the debugView...

<%@ Import Namespace="System.Diagnostics" %>

Then, at the top of the PlaceHolderMain section paste this code:

protected override void OnPreInit(EventArgs e)
{
     base.OnPreInit(e);

    Debug.WriteLine(SPContext.Current.File.Name);
}

 

Then, we are going to prepare a feature to reference this wkpcustom.aspx file in a SharePoint Foundation wiki page library.

Assume we call the feature

 Provisioning.SPF_WikiPages

Here is the feature.xml code:

<?xml version="1.0" encoding="utf-8"?>

<Feature Id="00BFEA71-2062-426C-90BF-714C59600AAA"

Title="Adding pre populate wiki pages"

Description="This feature will add pre-populate wiki pages to the site pages wiki library of this site"

Version="1.0.0.0"

Scope="Web"

Hidden="false"

DefaultResourceFile="core"

xmlns="http://schemas.microsoft.com/sharepoint/">

  <ElementManifests>

    <ElementManifest Location="elements.xml" />

  </ElementManifests>

</Feature>

And this is the xml code of the elements.xml file

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Url="SitePages" >

    <File Url="wkpcustom.aspx" Type="GhostableInLibrary"></File>

  </Module>

</Elements>

 

Last, a screen shot of the Provisioning.SPF_WikiPages feature folder

 

Then, install the feature and activate it for one of the team site of your Farm and you will have a reference to your page in the site pages library of this team site.

 

You can see a reference to the wkpcustom file located in the feature folder on the server

 

And because this file was provisioned by a feature, although there is in line code in it, if you display the wiki page using this file, it will work, the code will run and will write the name of the page in the debugview.

 

But, wait a minute, this file is already a template. It is a template for just one page within the site pages library but it is exactly like the wkpstd.aspx for the other pages. So assume we could have several pages within the library based on this file we would have created a new template. I see some of you smiling...

You have understood... It is what we are going to do now...

Now is the time to use another workaround I have already shown in a previous post to open our library in explorer mode.
So switch to shared documents library, open it in explorer mode, then using the explorer folder navigation go back to the site pages library but in explorer mode now

 

Then rename the page in "page 01.aspx"

 

then go back to the site pages library within the SharePoint UI. You will notice that the page is renamed and if you displayed it, its name in the debugview has changed too. While renamed, the page remains in its ghosted state and linked to the "template".

 

Now deactivate the feature, then reactivate it and you will have a new page wkpcustom.aspx beside the "page 01.aspx" and the two pages are linked to the same file on the server, so if we display one then the other, debugview will trace the two names based on the code of an unique file on the server: we have created our first custom template for a wiki page library in SharePoint Foundation!

 

Now we have done the demonstration we just have to find the way to do it programmatically:

Coding the sequence

this applicative page called from your site will provision 9 pages in your site page library pointing on the same unique template wkpcustom.aspx located in the feature folder. If you modify the file in the folder, you will modify the 9 pages

 

<%@ Page Language="C#" AutoEventWireup="true" Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase"

    DynamicMasterPageFile="~masterurl/default.master" %>

 

<%@ Assembly Name="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" %>

<%@ Import Namespace="Microsoft.SharePoint" %>

<%@ Import Namespace="Microsoft.SharePoint.Administration" %>

<%@ Import Namespace="System.Text" %>

<%@ Import Namespace="System.Linq" %>

<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

 

<asp:content id="PageHead" contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">

</asp:content>

<asp:content id="Main" contentplaceholderid="PlaceHolderMain" runat="server">

 

<script language="C#" runat="server">

 

    protected override void OnLoad(EventArgs e)

    {

        base.OnLoad(e);

 

        SPWeb myWeb = SPContext.Current.Web;

        myWeb.AllowUnsafeUpdates = true;

 

        for (int i = 1; i < 10; i++)

        {

 

            if (myWeb.Features[new Guid("{00BFEA71-2062-426C-90BF-714C59600AAA}")] != null)

            {

                myWeb.Features.Remove(new Guid("{00BFEA71-2062-426C-90BF-714C59600AAA}"));

            }

 

            myWeb.Features.Add(new Guid("{00BFEA71-2062-426C-90BF-714C59600AAA}"));

 

            SPList myList = myWeb.Lists["Site Pages"];

 

            SPListItem myItem = null;

 

            SPContext.Current.Web.AllowUnsafeUpdates = true;

 

            foreach (SPListItem anItem in myList.Items)

            {

                if (anItem.Name == "wkpcustom.aspx")

                {

                    myItem = anItem;

                }

            }

 

            string destinationUrl = myWeb.Url + "/" + myList.RootFolder.Url + "/" + "Wiki_page0" + i + ".aspx";

            myItem.File.MoveTo(destinationUrl);

            myItem.File.Update();

 

            myWeb.Features.Remove(new Guid("{00BFEA71-2062-426C-90BF-714C59600AAA}"));

        }

 

        lbl1.Text = "Your files has been provisionned successfully...";

    }

 

</script>

 

<asp:Label runat="server" ID="lbl1" ></asp:Label>

 

 

</asp:content>

<asp:content id="PageTitle" contentplaceholderid="PlaceHolderPageTitle" runat="server">

 

Provisioning Team Site Wiki Pages

 

</asp:content>

<asp:content id="PageTitleInTitleArea" contentplaceholderid="PlaceHolderPageTitleInTitleArea"

    runat="server">

 

Provisioning Team Site Wiki Pages

 

</asp:content>

 

 

Here are the screen shots of the applicative page after its provisioning job is finished

 

and the site pages library with the 9 new pages

 

And if I call the 9 pages, each of them will tell me its name.

 

And now, I have changed the instruction of the name displaying in the template, and I have called back the 9 pages and here is the result.

 

Have a lot of fun with that!