Forms Authentication 2 of 3

background image

Forms Authentication in SharePoint Products and Technologies (Part
2): Membership and Role Provider Samples

Summary: Explore details of developing a custom membership and role provider for Microsoft Office SharePoint
Server (MOSS) 2007 and Windows SharePoint Services 3.0, including the minimum required interfaces and how to
register and debug your custom provider. This article is part 2 of 3. (26 printed pages)

Steve Peschka, Microsoft Corporation

December 2007

Applies to: Microsoft Office SharePoint Server 2007, Windows SharePoint Services 3.0

Contents

z

Developing Custom Membership and Role Providers

z

Applying the XML File for the Data Source

z

Inheriting from the Membership and Role Base Classes

z

Minimum Interfaces Required by MOSS and Windows SharePoint Services

z

Registering the Custom Provider

z

Debugging the Custom Provider

z

Writing a Custom Forms Logon Page

z

Using Web Services with a Site Protected by Forms Authentication

z

Additional Resources

Read part 1 and part 3:

Forms Authentication in SharePoint Products and Technologies (Part 1): Introduction

[ http://msdn2.microsoft.com/en-us/library/bb975136(printer).aspx ]

Forms Authentication in SharePoint Products and Technologies (Part 3): Forms Authentication vs. Windows
Authentication

[ http://msdn2.microsoft.com/en-us/library/bb977430(printer).aspx ]

Developing Custom Membership and Role Providers

Applying the XML File for the Data Source

©2008 Microsoft Corporation. All rights

reserved.

Microsoft Office SharePoint Server (MOSS) 2007 and Windows SharePoint Services 3.0 (in this article series,
collectively referred to as SharePoint Products and Technologies) are built upon the ASP.NET 2.0 Framework. As
such, support for forms authentication extends not only to the membership and role providers that are included
with ASP.NET, MOSS, and Windows SharePoint Services, but also to custom membership and role providers. The
custom provider is required to inherit only from the ASP.NET membership or role base class respectively, and to
implement a limited set of interfaces on those classes.

Note:

Addressing this part of the Microsoft .NET Framework extensively is beyond the scope of this article. For
more information about the membership and role provider base classes, see

System.Web.Security.Membership

[ http://msdn2.microsoft.com/en-us/library/dazakw52

(printer).aspx ] and

System.Web.Security.RoleProvider

[ http://msdn2.microsoft.com/en-

us/library/kkdz3641(printer).aspx ] .

We now describe how to write a custom provider for users and roles that uses an XML file for the directory
information. The format of the XML file looks like the following code.

Important:

Strona 1 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Inheriting from the Membership and Role Base Classes

It is NOT a safe or secure practice to include unencrypted passwords in a clear text file, as displayed in
the following code example. We are using it in this case only to simplify the explanation of developing
custom providers. This is not an acceptable design for a production application. When storing sensitive
information in a configuration file for an application, you should encrypt the sensitive values by using
Protected Configuration. For more information, see

Encrypting Configuration Information Using

Protected Configuration

[ http://msdn2.microsoft.com/en-us/library/53tyfkaw(printer).aspx ] and

Securing Membership

[ http://msdn2.microsoft.com/en-us/library/ms178398(printer).aspx ] . If you

take the approach used as an example in this article, you are responsible for encrypting and decrypting
the data within your provider.

<

Users

>

<

User

name="user1" email="user1@microsoft.com" password="test" created="7/15/2007"

>

<

Groups

>

<

Group

>

Administrators

</

Group

>

<

Group

>

Authors

</

Group

>

<

Group

>

Readers

</

Group

>

</

Groups

>

</

User

>

<

User

name="user2" email="user2@microsoft.com" password="test" created="7/31/2007"

>

<

Groups

>

<

Group

>

Readers

</

Group

>

</

Groups

>

</

User

>

<

User

name="user3" email="user3@microsoft.com" password="test" created="8/15/2007"

>

<

Groups

>

<

Group

>

Designers

</

Group

>

<

Group

>

Readers

</

Group

>

</

Groups

>

</

User

>

</

Users

>

Xml

Copy Code

The base class that is used for membership is

System.Web.Security.MembershipProvider

[ http://msdn2.microsoft.com/en-us/library/sfka4yf8(printer).aspx ] ; if you are writing a custom membership
provider you must inherit from this class.

The base class that is used for roles is System.Web.Security.RoleProvider; if you are writing a custom role
provider you must inherit from this class.

using

System.Web;

using

System.Web.Security;

using

System.Xml;

using

System.Configuration;

namespace

Microsoft.IW

{

public

class

customUser : MembershipProvider

{

// This is not necessary for every provider; we are doing

// it for this one provider so that we can ensure our XML

// file is set up correctly.

private

XmlDocument xDoc =

null

;


// Code in here.

}

public

class

customRole : RoleProvider

{

// This is not necessary for every provider; we are doing

// it for this one provider so that we can ensure our XML

// file is set up correctly.

private

XmlDocument xDoc =

null

;


//Code in here.

}
}

C#

Copy Code

Imports

System.Web

Imports

System.Web.Security

Imports

System.Xml

Visual Basic

Copy Code

Strona 2 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Minimum Interfaces Required by MOSS and Windows SharePoint Services

Imports

System.Configuration

Namespace

Microsoft.IW

Public

Class

customUser

Inherits

MembershipProvider


' This is not necessary for every provider; we are doing

' it for this one provider so that we can ensure our XML

' file is set up correctly.

Private

xDoc

As

XmlDocument =

Nothing


' Code in here.

End

Class

Public

Class

customRole

Inherits

RoleProvider


' This is not necessary for every provider; we are doing

' it for this one provider so that we can ensure our XML

' file is set up correctly.

Private

xDoc

As

XmlDocument =

Nothing


' Code in here.

End

Class

End

Namespace

Both the MembershipProvider class and the RoleProvider class include several methods and properties. To
use the provider, only a subset of those is required by MOSS and Windows SharePoint Services.

To use the MembershipProvider, you must implement the following methods:

z

System.Web.Security.MembershipProvider.GetUser

[ http://msdn2.microsoft.com/en-us/library/ms152043

(printer).aspx ]

z

System.Web.Security.MembershipProvider.GetUserNameByEmail(System.String)

[ http://msdn2.microsoft.com/en-us/library/57hsxfsd(printer).aspx ]

z

System.Web.Security.MembershipProvider.ValidateUser(System.String,System.String)

[ http://msdn2.microsoft.com/en-us/library/05d03b82(printer).aspx ]

z

System.Web.Security.MembershipProvider.FindUsersByEmail
(System.String,System.Int32,System.Int32,System.Int32)

[ http://msdn2.microsoft.com/en-

us/library/96e54ch9(printer).aspx ]

z

System.Web.Security.MembershipProvider.FindUsersByName
(System.String,System.Int32,System.Int32,System.Int32)

[ http://msdn2.microsoft.com/en-

us/library/89e8kx21(printer).aspx ]

To use the RoleProvider, you must implement the following methods:

z

System.Web.Security.RoleProvider.GetRolesForUser(System.String)

[ http://msdn2.microsoft.com/en-

us/library/wzdyk8sx(printer).aspx ]

z

System.Web.Security.RoleProvider.RoleExists(System.String)

[ http://msdn2.microsoft.com/en-

us/library/5t22kc66(printer).aspx ]

In addition to the methods that SharePoint Products and Technologies require, the class contract requires you to
implement some additional methods and properties. In those cases, you can either implement the functionality or
choose to throw a

System.NotSupportedException

[ http://msdn2.microsoft.com/en-us/library/8a7a4e64

(printer).aspx ] . For example, the MembershipProvider requires a

System.Web.Security.MembershipProvider.ChangePassword(System.String,System.String,System.String)

[ http://msdn2.microsoft.com/en-us/library/bdt44e91(printer).aspx ] method; if you do not want to support that
functionality, your override of that method should resemble the following code.

Note:

The following section contains several code examples meant to demonstrate only the implementation of
the minimum interfaces required to have a custom membership and role provider that is usable with
MOSS 2007 and Windows SharePoint Services 3.0. They are not meant to demonstrate coding best
practices.

Strona 3 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

As with most custom providers, this example includes special code to work with the data store: in this case, an
XML file. A simple helper class was developed to read the file from a hard-coded location on disk and store it in
cache. The item was added into cache with a dependency so that if the file on disk changes, such as when a user
is added or removed, the XML file is purged from cache. Following is the code for the helper class.

public

override

bool

ChangePassword(

string

username,

string

oldPassword,

string

newPassword)
{
throw

new

NotSupportedException();

}

C#

Copy Code

Public

Overrides

Function

ChangePassword(

ByVal

username

As

String

,

ByVal

oldPassword

As

String

,

ByVal

newPassword

As

String

)

As

Boolean

Throw

New

NotSupportedException()

End

Function

Visual Basic

Copy Code

using

System;

using

System.Collections.Generic;

using

System.Text;

using

System.Xml;

using

System.Diagnostics;

using

System.Web;

namespace

Microsoft.IW

{
internal

class

Helper

{

private

const

string

XML_PATH =

"c:\\inetpub\\wwwroot\\userdata\\users.xml"

;

private

const

string

XML_CACHE =

"xmlUserDocFile"

;


public

static

XmlDocument GetXmlFile()

{

// This helper function looks for the XML document

// in cache; if it is there,

// it pulls it out of cache. Otherwise, it loads

// it into an XML document

// and stores it in cache with a file cache

// dependency, so that if the

// the XML file changes it will be flushed out

// of cache and have to be reread and reloaded.


XmlDocument xDoc =

null

;


try

{

// Look for the item in cache.

if

(HttpContext.Current.Cache[XML_CACHE] ==

null

)

{

// Create a new document.

xDoc =

new

XmlDocument();


// Load it from disk.

xDoc.Load(XML_PATH);

// Save it to cache.

HttpContext.Current.Cache.Insert(XML_CACHE,
xDoc,

new

System.Web.Caching.CacheDependency(XML_PATH));
}

else

xDoc =
(XmlDocument)HttpContext.Current.Cache[XML_CACHE];
}

catch

(Exception ex)

{

// Try writing to the event log.

try

{
EventLog.WriteEntry(

"fbaSharp Custom Provider"

,

"Error loading user xml file: "

+

ex.Message, EventLogEntryType.Error);
}

C#

Copy Code

Strona 4 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Functions Required in a Custom Membership Provider

catch

{

// Ignore.

}
}

return

xDoc;

}
}
}

Imports

System.Xml

Imports

System.Diagnostics

Imports

System.Web

Namespace

Microsoft.IW

Friend

Class

Helper

Private

Const

XML_PATH

As

String

= _

"c:\inetpub\wwwroot\userdata\users.xml"

Private

Const

XML_CACHE

As

String

=

"xmlUserDocFile"

Public

Shared

Function

GetXmlFile()

As

XmlDocument


' This helper function looks for the XML document

' in cache; if it is there, it pulls it out of cache.

' Otherwise, it loads it into an XML document and

' stores it in cache with a file cache dependency,

' so that if the XML file changes it will be

' flushed out of cache and have to be reread

' and reloaded.


Dim

xDoc

As

XmlDocument =

Nothing


Try

' Look for the item in cache.

If

HttpContext.Current.Cache(XML_CACHE)

Is

Nothing

Then

' Create a new document.

xDoc =

New

XmlDocument


' Load it from disk.

xDoc.Load(XML_PATH)

' Save it to cache.

HttpContext.Current.Cache.Insert(XML_CACHE, xDoc, _

New

System.Web.Caching.CacheDependency(XML_PATH))

Else

xDoc = HttpContext.Current.Cache(XML_CACHE)

End

If

Catch

ex

As

Exception

' Try writing to event log.

Try

EventLog.WriteEntry(

"fbaVB Custom Provider"

, _

"Error loading user xml file: "

& _

ex.Message, EventLogEntryType.Error)

Catch

logEx

As

Exception

' Ignore.

End

Try

End

Try

Return

xDoc

End

Function

End

Class

End

Namespace

Visual Basic

Copy Code

The following sections describe the functions (methods) required in a custom membership provider.

GetUser Method

The GetUser function has two overridden implementations and returns a

System.Web.Security.MembershipUser

[ http://msdn2.microsoft.com/en-us/library/d1b506ez(printer).aspx ] object based on user name and a flag that
indicates whether a user is online. As with any class, the author must determine whether and how to use the
parameters that are passed to it. For example, in most cases it is unlikely that you would change the return value
from this function based only on whether the user is online. Notice that the providerUserKey is useful only if
you are using a single Membership database to store users for multiple applications and you need to distinguish

Strona 5 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

in which of those applications the user exists. You can find more detail about this parameter on MSDN in the
Membership classes materials that are referenced at the beginning of this article. This parameter is controlled in
the applicationName attribute of the add element in the web.config file that is used to define a membership
provider.

public

override MembershipUser GetUser(object providerUserKey,

bool

userIsOnline)

{
MembershipUser ret =

null

;

XmlNode xNode =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for a user with a name that matches.

xNode = xDoc.SelectSingleNode(

"/Users/User[@name='"

+

providerUserKey.ToString() +

"']"

);


// Determine whether there are any matches.

if

(xNode !=

null

)

{

// Create a new membershipusercollection.

ret =

new

MembershipUser(Membership.Provider.Name,

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"email"

].Value.ToString(),

string

.Empty,

string

.Empty,

true

,

false

,

DateTime.Parse(xNode.Attributes[

"created"

].Value.ToString()),

DateTime.Today, DateTime.Today, DateTime.Today,
DateTime.MinValue);
}
}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

public

override MembershipUser GetUser(

string

username,

bool

userIsOnline)

{
MembershipUser ret =

null

;

XmlNode xNode =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for a user with a name that matches.

xNode = xDoc.SelectSingleNode(

"/Users/User[@name='"

+

username +

"']"

);


// See if there are any matches.

if

(xNode !=

null

)

{

// Create a new membershipusercollection.

ret =

new

MembershipUser(Membership.Provider.Name,

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"email"

].Value.ToString(),

string

.Empty,

string

.Empty,

true

,

false

,

DateTime.Parse(xNode.Attributes[

"created"

].Value.ToString()),

DateTime.Today, DateTime.Today, DateTime.Today,
DateTime.MinValue);

C#

Copy Code

Strona 6 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

}
}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

Public

Overloads

Overrides

Function

GetUser(_

ByVal

providerUserKey

As

Object

,

ByVal

userIsOnline

As

Boolean

) _

As

System.Web.Security.MembershipUser

Dim

ret

As

MembershipUser =

Nothing

Dim

xNode

As

XmlNode =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for a user with a name that matches.

xNode = xDoc.SelectSingleNode("/Users/User[@name=

'" & _

providerUserKey.ToString() & "

']")


' See if there are any matches.

If

xNode IsNot

Nothing

Then

'Create a new membershipusercollection.

ret =

New

MembershipUser(Membership.Provider.Name, _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"email"

).Value.ToString(), _

String

.Empty,

String

.Empty,

True

,

False

, _

Date

.Parse(xNode.Attributes(

"created"

).Value.ToString()), _

Date

.Today,

Date

.Today,

Date

.Today,

Date

.MinValue)

End

If

End

If

Catch

ex

As

Exception

'Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

Public

Overloads

Overrides

Function

GetUser( _

ByVal

username

As

String

,ByVal userIsOnline

As

Boolean

) _

As

System.Web.Security.MembershipUser

Dim

ret

As

MembershipUser =

Nothing

Dim

xNode

As

XmlNode =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for a user with a name that matches.

xNode = xDoc.SelectSingleNode("/Users/User[@name=

'" & _

username & "

']")


' See if there are any matches.

If

xNode IsNot

Nothing

Then

' Create a new membershipusercollection.

ret =

New

MembershipUser(Membership.Provider.Name, _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"email"

).Value.ToString(), _

String

.Empty,

String

.Empty,

True

,

False

, _

Visual Basic

Copy Code

Strona 7 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

GetUserNameByEmail Method

The GetUserNameByEmail function takes an e-mail address as a parameter and looks for a user with that e-
mail address. If it finds such a user, it returns the user name.

Date

.Parse(xNode.Attributes(

"created"

).Value.ToString()), _

Date

.Today,

Date

.Today,

Date

.Today,

Date

.MinValue)

End

If

End

If

Catch

ex

As

Exception

'Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

public

override

string

GetUserNameByEmail(

string

email)

{

string

ret =

string

.Empty;

XmlNode xNode =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for the user.

xNode = xDoc.SelectSingleNode(

"/Users/User[@email='"

+

email +

"']"

);


// See if it found a match.

if

(xNode !=

null

)

ret = xNode.Attributes[

"name"

].Value.ToString();

}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

C#

Copy Code

Public

Overrides

Function

GetUserNameByEmail(

ByVal

email

As

String

) _

As

String

Dim

ret

As

String

=

String

.Empty

Dim

xNode

As

XmlNode =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for the user.

xNode = xDoc.SelectSingleNode("/Users/User[@email=

'" & _

email & "

']")


' See if it found a match.

If

xNode IsNot

Nothing

Then

_

ret = xNode.Attributes(

"name"

).Value.ToString

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Visual Basic

Copy Code

Strona 8 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

ValidateUser Method

The ValidateUser function takes a user name and password and verifies whether it is correct.

Return

ret

End

Function

public

override

bool

ValidateUser(

string

username,

string

password)

{

bool

ret =

false

;

XmlNode xNode =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for the user.

xNode = xDoc.SelectSingleNode(

"/Users/User[@name='"

+

username +

"']"

);


// See if it found a match.

if

(xNode !=

null

)

{

// Look for the password attribute to see if it matches.

if

(xNode.Attributes[

"password"

].Value.ToString() == password)

ret =

true

;

}
}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

C#

Copy Code

Public

Overrides

Function

ValidateUser(

ByVal

username

As

String

, _

ByVal

password

As

String

)

As

Boolean

Dim

ret

As

Boolean

=

False

Dim

xNode

As

XmlNode =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for the user.

xNode = xDoc.SelectSingleNode("/Users/User[@name=

'" & _

username & "

']")


' See if it found a match.

If

xNode IsNot

Nothing

Then

' Look for the password attribute to see if it matches.

If

xNode.Attributes(

"password"

).Value.ToString = password

Then

_

ret =

True

End

If

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

Visual Basic

Copy Code

Strona 9 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

FindUsersByEmail Method

The FindUsersByEmail function takes an e-mail address as a parameter and finds all users whose e-mail
addresses start with that value. It returns a

System.Web.Security.MembershipUserCollection

[ http://msdn2.microsoft.com/en-us/library/3xe386wc(printer).aspx ] object.

public

override MembershipUserCollection FindUsersByEmail(

string

emailToMatch,

int

pageIndex,

int

pageSize, out

int

totalRecords)

{
MembershipUserCollection ret =

null

;

XmlNodeList xList =

null

;


// Initialize the number of records found.

totalRecords = 0;

try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for users with matching e-mail addresses.

xList = xDoc.SelectNodes(

"/Users/User[starts-with(@email, '"

+

emailToMatch +

"')]"

);


// See if there are any matches.

if

((xList !=

null

) && (xList.Count > 0))

{

// Set the number of records found.

totalRecords = xList.Count;

// Create a new membershipusercollection.

ret =

new

MembershipUserCollection();


// Enumerate each match and add it to the collection.

foreach

(XmlNode xNode

in

xList)

{
ret.Add(

new

MembershipUser(Membership.Provider.Name,

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"email"

].Value.ToString(),

string

.Empty,

string

.Empty,

true

,

false

,

DateTime.Parse(xNode.Attributes[

"created"

].Value.ToString()),

DateTime.Today, DateTime.Today, DateTime.Today,
DateTime.MinValue));
}
}
}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

C#

Copy Code

Public

Overrides

Function

FindUsersByEmail(

ByVal

emailToMatch

As

_

String

,

ByVal

pageIndex

As

Integer

,

ByVal

pageSize

As

Integer

, _

ByRef

totalRecords

As

Integer

)

As

_

System.Web.Security.MembershipUserCollection

Dim

ret

As

MembershipUserCollection =

Nothing

Dim

xList

As

XmlNodeList =

Nothing

' Initialize the number of records found.

totalRecords = 0

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

Visual Basic

Copy Code

Strona 10 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

FindUsersByName Method

The FindUserByName function works the same way that the FindUserByEmail function does; however, it takes
a user name (full or partial) as a parameter.

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for users with matching e-mail addresses.

xList = xDoc.SelectNodes("/Users/User[starts-with(@email,

'" & _

emailToMatch & "

')]")


' See if there are any matches.

If

xList IsNot

Nothing

AndAlso

xList.Count > 0

Then

' Set the number of records found.

totalRecords = xList.Count

' Create a new membershipusercollection.

ret =

New

MembershipUserCollection()


' Enumerate each match and add it to the collection.

For

Each

xNode

As

XmlNode

In

xList

ret.Add(

New

MembershipUser(Membership.Provider.Name, _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"email"

).Value.ToString(), _

String

.Empty,

String

.Empty,

True

,

False

, _

Date

.Parse(xNode.Attributes(

"created"

).Value.ToString()), _

Date

.Today,

Date

.Today,

Date

.Today,

Date

.MinValue))

Next

End

If

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

public

override MembershipUserCollection FindUsersByName(

string

usernameToMatch,

int

pageIndex,

int

pageSize, out

int

totalRecords)

{

MembershipUserCollection ret =

null

;

XmlNodeList xList =

null

;


// Initialize the number of records found.

totalRecords = 0;

try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for users with matching e-mail addresses.

xList = xDoc.SelectNodes(

"/Users/User[starts-with(@name, '"

+

usernameToMatch +

"')]"

);


// See if there are any matches.

if

((xList !=

null

) && (xList.Count > 0))

{

// Create a new membershipusercollection.

ret =

new

MembershipUserCollection();


// Enumerate each match and add it to the collection.

foreach

(XmlNode xNode

in

xList)

{
ret.Add(

new

MembershipUser(Membership.Provider.Name,

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"name"

].Value.ToString(),

xNode.Attributes[

"email"

].Value.ToString(),

string

.Empty,

string

.Empty,

true

,

false

,

C#

Copy Code

Strona 11 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Functions Required in a Custom Role Provider

DateTime.Parse(xNode.Attributes[

"created"

].Value.ToString()),

DateTime.Today, DateTime.Today, DateTime.Today,
DateTime.MinValue));
}
}
}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

Public

Overrides

Function

FindUsersByName( _

ByVal

usernameToMatch

As

String

,

ByVal

pageIndex

As

Integer

, _

ByVal

pageSize

As

Integer

,

ByRef

totalRecords

As

Integer

) _

As

System.Web.Security.MembershipUserCollection

Dim

ret

As

MembershipUserCollection =

Nothing

Dim

xList

As

XmlNodeList =

Nothing

' Initialize the number of records found.

totalRecords = 0

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for users with matching e-mail addresses.

xList = xDoc.SelectNodes("/Users/User[starts-with(@name,

'" & _

usernameToMatch & "

')]")


' See if there are any matches.

If

xList IsNot

Nothing

AndAlso

xList.Count > 0

Then

'create a new membershipusercollection

ret =

New

MembershipUserCollection()


' Enumerate each match and add it to the collection.

For

Each

xNode

As

XmlNode

In

xList

ret.Add(

New

MembershipUser(Membership.Provider.Name, _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"name"

).Value.ToString(), _

xNode.Attributes(

"email"

).Value.ToString(), _

String

.Empty,

String

.Empty,

True

,

False

, _

Date

.Parse(xNode.Attributes(

"created"

).Value.ToString()), _

Date

.Today,

Date

.Today,

Date

.Today,

Date

.MinValue))

Next

End

If

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

Visual Basic

Copy Code

The following sections describe functions (methods) that are required in a custom role provider.

GetRolesForUser Method

The GetRolesForUser function takes a user name as a parameter and returns a string array that contains the
names of all groups to which the user belongs.

Important:

Strona 12 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

You must understand one limitation when you are writing code for the GetRolesForUser method. The
role provider has a property named

System.Web.Security.Roles.CacheRolesInCookie

[ http://msdn2.microsoft.com/en-us/library/f46tewk7(printer).aspx ] . Unfortunately, because of a bug
that exists in ASP.NET at the time this article was written, that attribute is not honored, and the role
provider's GetRolesForUser method is called every time. In practice, the GetRolesForUser method is
called at least once for every user, for every page that he or she visits in the SharePoint site. Because
of this, you should implement your own caching mechanism in the GetRolesForUser method in any
custom role provider.

public

override

string

[] GetRolesForUser(

string

username)

{

string

[] ret =

null

;

XmlNode xNode =

null

;

XmlNodeList xList =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for the user.

xNode = xDoc.SelectSingleNode(

"/Users/User[@name='"

+

username +

"']"

);


// See if it found a match.

if

(xNode !=

null

)

{

// Get the collection of group nodes.

xList = xNode.ChildNodes[0].ChildNodes;

// Resize the array based on number of child nodes.

ret =

new

string

[xList.Count];


// Enumerate all the groups in the Groups/Group subnodes

// and add to return value.

for

(

int

cnt = 0;cnt < xList.Count;cnt++)

{
ret[cnt] = xList.Item(cnt).InnerText;
}
}
}
}

catch

{

// Take appropriate action.

}

//Return the results.

return

ret;

}

C#

Copy Code

Public

Overrides

Function

GetRolesForUser(

ByVal

username

As

String

) _

As

String

()

Dim

ret

As

String

() =

Nothing

Dim

xNode

As

XmlNode =

Nothing

Dim

xList

As

XmlNodeList =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for the user.

xNode = xDoc.SelectSingleNode("/Users/User[@name=

'" & _

username & "

']")


' See if it found a match.

If

xNode IsNot

Nothing

Then

Visual Basic

Copy Code

Strona 13 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

RoleExists Method

The RoleExists function takes a role name as a parameter. If the role exists, the function returns true;
otherwise, it returns false.

' Get the collection of group nodes.

xList = xNode.ChildNodes(0).ChildNodes

' Resize the array based on number of child nodes.

ReDim

ret(xList.Count - 1)


' Enumerate all the groups in the Groups/Group subnodes and

' add to return value.

For

cnt

As

Integer

= 0

To

xList.Count - 1

ret(cnt) = xList.Item(cnt).InnerText

Next

End

If

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

public

override

bool

RoleExists(

string

roleName)

{

bool

ret =

false

;

XmlNode xNode =

null

;


try

{

// Get the XML document.

xDoc = Helper.GetXmlFile();

// Proceed if it contains something.

if

(xDoc !=

null

)

{

// Look for the role.

xNode = xDoc.SelectSingleNode(

"/Users/User[Groups/Group='"

+

roleName +

"']"

);


// Return true if it found a match.

if

(xNode !=

null

) ret =

true

;

}
}

catch

{

// Take appropriate action.

}

// Return the results.

return

ret;

}

C#

Copy Code

Public

Overrides

Function

RoleExists(

ByVal

roleName

As

String

) _

As

Boolean

Dim

ret

As

Boolean

=

False

Dim

xNode

As

XmlNode =

Nothing

Try

' Get the XML document.

xDoc = Helper.GetXmlFile()

' Proceed if it contains something.

If

xDoc IsNot

Nothing

Then


' Look for the role.

xNode = xDoc.SelectSingleNode("/Users/User[Groups/Group=

'" & _

roleName & "

']")


' Return true if it found a match.

If

xNode IsNot

Nothing

Then

ret =

True

Visual Basic

Copy Code

Strona 14 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Registering the Custom Provider

End

If

Catch

ex

As

Exception

' Take appropriate action.

End

Try

' Return the results.

Return

ret

End

Function

Now that you understand the minimum required interfaces for a custom Membership and Role provider to work
with MOSS 2007 and Windows SharePoint Services 3.0. your next step is to register the custom provider.

To be able to use a custom provider, you must provide a strong name for the assembly it uses, and then register
it in the global assembly cache.

To strong name the assembly

1. In Microsoft Visual Studio, right-click the project name, and then click Properties.

2. Click the Signing tab, and then select Sign the assembly.

3. In the Choose a strong name key file list, click <New…>.

4. In the Create Strong Name Key dialog box, type a name for the key file, optionally type a password for the

key file, and then click OK.

When you compile the assembly, it builds with the strong name you provided.

You can now add your strong-named assembly to the global assembly cache in several ways, but the most
common way is to use the

gacutil.exe

[ http://msdn2.microsoft.com/en-us/library/ex0ss12c(printer).aspx ] utility

with the /i option. For more information about installing an assembly in the global assembly cache, see

How to:

Install an Assembly into the Global Assembly Cache

[ http://msdn2.microsoft.com/en-us/library/dkkx7f79

(printer).aspx ] .

After you register the assembly, you can extend a Web application into a zone and configure it to use your
custom provider (described in the "Setting Up Forms Authentication" section of

Forms Authentication in

SharePoint Products and Technologies (Part 1): Introduction

[ http://msdn2.microsoft.com/en-

us/library/bb975136(printer).aspx ] ).

Following are two different example entries for the custom provider, reflecting that the Microsoft Visual C# and
Microsoft Visual Basic assemblies were created with different names. In the examples, when you configure the
authentication provider for the zone, the authentication method should be Forms, the membership provider
name should be fbaUser, and the role manager name should be fbaRole.

For the Visual C# assembly, use the following code.

For the Visual Basic assembly, use the following code.

Note:

Because the strong name for an assembly that you compile on your computer will differ from the
following example, the entries for your custom provider will also differ slightly; specifically the
PublicKeyToken value will be different.

<

membership

defaultProvider="fbaUser"

>

<

providers

>

<

add

name="fbaUser" type="Microsoft.IW.customUser, fbaSharp, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=b74d22b2d68547b5"

/>

</

providers

>

</

membership

>

<

roleManager

enabled="true" defaultProvider="fbaRole"

>

<

providers

>

<

add

name="fbaRole" type="Microsoft.IW.customRole, fbaSharp, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=b74d22b2d68547b5"

/>

</

providers

>

</

roleManager

>

Xml

Copy Code

Strona 15 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Debugging the Custom Provider

<

membership

defaultProvider="fbaUser"

>

<

providers

>

<

add

name="fbaUser" type="Microsoft.IW.customUser, fbaVB, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=ddd85720e6ace42b"

/>

</

providers

>

</

membership

>

<

roleManager

enabled="true" defaultProvider="fbaRole"

>

<

providers

>

<

add

name="fbaRole" type="Microsoft.IW.customRole, fbaVB, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=ddd85720e6ace42b"

/>

</

providers

>

</

roleManager

>

Xml

Copy Code

Now that you have compiled the assembly, registered it, and configured a new zone to use the custom provider,
you can use and (optionally) debug the provider. You would debug the custom provider in the same way that you
would debug any other assembly that is used by another process. In this case, the process that is consuming the
assembly is the w3wp.exe process.

To debug the provider, you set the breakpoints you want in the code, and then attach to the w3wp.exe process.

To attach to the w3wp.exe

1. In Visual Studio, on the Tools menu, click Attach to Process to open the Attach to Process dialog box.

2. In Available Processes, select the w3wp.exe process, and then click Select.

z

If you do not see any w3wp processes, select Show processes from all users.

z

Also, if you have recently performed an iisreset, you must navigate to a page in the SharePoint site to
create a new w3wp.exe process. Conversely, you might also find multiple w3wp.exe processes running.
In such a case, select all w3wp.exe processes. This ensures that you attach to the process that is
running your provider assembly.

After you attach the w3wp.exe process, try logging on to the site. If you attached a breakpoint on the
ValidateUser method of your membership provider, the breakpoint should be hit at the time you log on. If the
breakpoint is not hit, you should try reattaching to the w3wp.exe process; another process might have started in
connection with logging on to the site. The processes that are already attached appear dimmed (they are
disabled); any new w3wp.exe processes appear black and are enabled to allow attachments.

As you log on and navigate to pages, you should see breakpoints being hit in both the membership and role
providers. To test your providers further, try using the People Picker to search for users and roles to add to
SharePoint groups. This triggers breakpoints set in any of the membership and role provider methods. The
number of times the breakpoints are hit varies on what is being done. When you use the People Picker, some
methods such as FindUserByEmail can be called more than once. The number of times the role provider is
called for any given page can vary also. The role provider is called for each item on the page that requires
authentication. Some examples of items are navigation, list view Web Parts, or parts that are targeted at
audiences. As a result, the GetRolesForUser method in the role provider is called one or more times for every
user on each page view.

Figure 1 and Figure 2 show the People Picker, configured to use the custom membership and role providers.
Notice the account name for the entities matches the name attribute of the membership and role provider, as
described earlier.

Figure 1. Select People and Groups - membership provider name

Strona 16 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Writing a Custom Forms Logon Page

Figure 2. Select People and Groups - role provider name

You may have scenarios that have special logon requirements that cannot be addressed by the default SharePoint
forms logon page. For example, you may need to implement a second authentication factor such as Secure ID.
Fortunately, because SharePoint Products and Technologies are built on top of ASP.NET 2.0, you can create a
custom logon page with your own logon logic, and integrate it directly into MOSS or Windows SharePoint
Services.

Creating a Standard ASP.NET Web Site

Strona 17 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

The easiest way to create a custom logon page is to build a standard ASP.NET Web application. This enables you
to create a site and easily debug the code behind for your forms logon page to ensure that it is working correctly.
When you do this, you should configure your site to use the same membership and role provider that you intend
to use with MOSS or Windows SharePoint Services.

In the scenario for this article, we built a custom forms logon page for two reasons:

z

To show a custom policy condition that all site users must agree to before using the site.

z

To force certain users to use two-factor authentication, where the second factor is Secure ID.

We have created an ASPX page named customLogin.aspx and added it to the site. It contains the following:

z

Edit boxes for user name, password, and Secure ID number

z

A check box for a persistent authorization cookie

z

A button to perform the logon process

Figure 3 shows how the page should look.

Figure 3. customLogin.aspx page

The web.config file was modified to do the following:

z

Use forms authentication and the fbaVB membership and role provider described earlier in this article, in
the section

Registering the Custom Provider

.

z

Deny access to anonymous users.

Default.aspx was also added to the site when the project was created, and it is used in the site for testing.

Adding Code Behind the Logon Page

In the code behind the logon page, you should first validate the credentials. You can use the ValidateUser
method of the Membership class to do this. If the credentials are valid, you can redirect the user to the site;
otherwise, prompt them to reenter their credentials.

if

(Membership.ValidateUser(UserTxt.Text, PwdTxt.Text))

{

// Do Secure ID thing here.

// Redirect the user to the requested page.

FormsAuthentication.RedirectFromLoginPage(UserTxt.Text,
SaveChk.Checked);
}

else

StatusLbl.Text =

"The credentials you entered are not valid. "

+

"Please try again."

;

C#

Copy Code

If

Membership.ValidateUser(UserTxt.Text, PwdTxt.Text)

Then

Visual Basic

Copy Code

Strona 18 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

For the Secure ID component, this example simulates only the process that a user or another system that
requires additional authentication processing would go through. In this example, the page is hard-coded to
prompt a specific user for a Secure ID number; in practice you could query a database or Web service (or
whatever is appropriate) to determine how to process users. After prompting the user for the Secure ID
credentials, it allows them to pass.

Compiling the Application into an Assembly

After you complete the simple ASP.NET application and have the forms logon page working correctly, your next
step is to compile it and use it in MOSS or Windows SharePoint Services. You can use the Web site project that is
new with Visual Studio 2005 to create the Web application. Alternatively, with Service Pack 1 of Visual Studio you
can also create the Web project model that is similar to Visual Studio 2003, in that you can compile the project
into a single assembly (.dll file).

For the remainder of this section, we assume that you have compiled the project into a single assembly. If you
use the Visual Studio 2005 style of Web site project, you can still make the application work, but you must use
the

ASP.NET Compilation Tool (Aspnet_compiler.exe)

[ http://msdn2.microsoft.com/en-us/library/ms229863

(printer).aspx ] to precompile it. If you use that approach, ensure that you include the -u parameter when you
compile so that you can update the assembly later.

Copying Files and Registering the Assembly

Following are the steps to make the custom logon page available to MOSS or Windows SharePoint Services.

To enable the use of the custom logon page by SharePoint Products and Technologies

1. Copy the logon page to the _layouts directory. The default path is C:\Program Files\Common

Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS

.

2. Create a bin directory on the file system at the top-level (root) of your SharePoint Web application that will

use your custom logon page. For the examples used in this article, the default directory would be in the path
C:\Inetpub\wwwroot\wss\VirtualDirectories\ www.contoso.com80

. Then, copy the compiled assembly

for the custom forms application to the bin directory that you created.

3. Register the compiled assembly for the custom forms application in the global assembly cache. You can do

this by using the

Global Assembly Cache Tool (Gacutil.exe)

[ http://msdn2.microsoft.com/en-

us/library/ex0ss12c(printer).aspx ] with the /i option. For more details about installing an assembly in the
global assembly cache, see

How to: Install an Assembly into the Global Assembly Cache

' Do Secure ID thing here.

' Redirect the user to the requested page.

FormsAuthentication.RedirectFromLoginPage(UserTxt.Text, _
SaveChk.Checked)

Else

StatusLbl.Text =

"The credentials you entered are not valid. "

& _

Please

try

again."

End

If

// Instead of redirecting user3, ask for a Secure ID number.

if

(UserTxt.Text.ToLower() ==

"user3"

)

{

// Update UI.

StatusLbl.Text =

"Please enter your Secure ID number"

;

LogPnl.Visible =

false

;

SecurePnl.Visible =

true

;

}

C#

Copy Code

' Instead of redirecting user3, ask for a Secure ID number.

If

UserTxt.Text.ToLower() =

"user3"

Then

' Update UI.

StatusLbl.Text =

"Please enter your Secure ID number"

LogPnl.Visible =

False

SecurePnl.Visible =

True

End

If

Visual Basic

Copy Code

Note:

It is often easier to debug integrated solutions such as this if you use the latter approach and compile
the Web application into a single DLL.

Strona 19 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

[ http://msdn2.microsoft.com/en-us/library/dkkx7f79(printer).aspx ] .

You must also update the web.config file for the Web application that is going to use the custom logon page.

To update the web.config file for the Web application

1. Open the web.config file.

2. In the authentication section, locate the forms element.

3. In the forms element, change the loginUrl attribute to point to your new custom forms logon page; for

example, _layouts/customLogin.aspx.

4. Perform an iisreset.

You should now be able to use the custom logon page.

Following is an example of what the page looks like when used with the Contoso site described earlier in this
article.

Figure 4. customLogin.aspx page on Contoso site

The interface is obviously not quite what one would expect from a SharePoint site. Fortunately, you can copy
elements from the login.aspx page that is included with SharePoint Products and Technologies and paste them
into the custom logon page to give it the SharePoint appearance.

To modify the custom logon page to give it the SharePoint appearance

1. In the @ Page directive at the top of the page, add the following master page attribute.

2. Remove the following lines from near the top of the page.

3. Add the following lines directly below the @ Page directive.

Note:

This step is important; things might not work correctly if you do not perform an iisreset.

MasterPageFile="~/_layouts/simple.master"

Html

Copy Code

<!

DOCTYPE

html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

>

<

html

>

<

head

id="Head1" runat="server"

>

<

title

>

Untitled Page

</

title

>

</

head

>

<

body

>

<

form

id="form1" runat="server"

>

Html

Copy Code

Html

Copy Code

Strona 20 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

4. Remove the following lines from the bottom of the page.

5. Add the following line to the bottom of the page.

Try logging on to the site again; you may need to refresh the page. After you refresh, the page should look like
Figure 5 and Figure 6.

Figure 5. Updated customLogin.aspx on Contoso site - enter user name and password

Figure 6. Updated customLogin.aspx on Contoso site - enter Secure ID

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

<%

@ Register Tagprefix="SharePoint"

Namespace="Microsoft.SharePoint.WebControls"

Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,

PublicKeyToken=71e9bce111e9429c"

%>

<%

@ Register Tagprefix="Utilities"

Namespace="Microsoft.SharePoint.Utilities"

Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,

PublicKeyToken=71e9bce111e9429c"

%>

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

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

<

SharePoint:EncodedLiteral

runat="server" text="

<%

$Resources:wss,login_pagetitle

%

>

" EncodeMethod='HtmlEncode'

/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderTitleBreadcrumb" runat="server">

&nbsp;

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

<

SharePoint:EncodedLiteral

runat="server" text="

<%

$Resources:wss,login_pagetitle

%

>

" EncodeMethod='HtmlEncode'

/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

</

form

>

</

body

>

</

html

>

Html

Copy Code

</asp:Content>

Html

Copy Code

Strona 21 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Using Web Services with a Site Protected by Forms Authentication

Using the SharePoint Web services with a site secured with forms authentication works; however, the process
differs from what you would do to use Web services for a site that is secured with Windows authentication. The
primary difference is that you must obtain an authentication cookie and then use that cookie when accessing the
Web services in the site protected by forms authentication.

Fortunately, SharePoint Products and Technologies provide a new Web service that makes it easier to work in this
scenario: the

Authentication Web service

[ http://msdn2.microsoft.com/en-us/library/aa979750(printer).aspx ] .

It has a method named

Login

[ http://msdn2.microsoft.com/en-us/library/aa979746(printer).aspx ] that, when

called, places an authentication cookie in the proxy's

System.Web.Services.Protocols.HttpWebClientProtocol.CookieContainer

[ http://msdn2.microsoft.com/en-

us/library/yta0fyx9(printer).aspx ] collection. That cookie can then be used in subsequent requests to other Web
services in the site that is protected by forms authentication to authenticate the request.

For purposes of creating your Web service proxies (such as

adding Web references in Visual Studio

[ http://msdn2.microsoft.com/en-us/library/8dcbc50t(printer).aspx ] ), use a Windows authentication–protected
site. In most cases, the Visual Studio Add Web Reference wizard does not work with a SharePoint site that is
protected by forms authentication. For this example, we retrieve all of the lists in the site by using the

Lists Web

service

[ http://msdn2.microsoft.com/en-us/library/ms774654(printer).aspx ] .

To retrieve all lists in the site by using the Lists Web services

1. Start Visual Studio, and create a Windows Application project.

2. Add a button and text box to Form1.

3. Change the text box properties so that Multiline is True and Scrollbars is Vertical.

4. Resize the text box to fill the form under the button.

5. Add a Web reference to the Authentication Web service in the site that is protected by forms

authentication; the Authentication Web service can be found in the path
http://siteCollectionName/_vti_bin/authentication.asmx

. Name this Web reference fbaAuth.

6. Add a second Web reference to the Lists Web service; it can be found in the path

http://siteCollectionName/_vti_bin/lists.asmx

. Name this Web reference fbaLists.

7. On the form, double-click Button1 to switch to code view and create an event handler for the click event.

Create two variables for the Web service proxies, as shown in the following code.

Note:

By default, a zone that is configured to use forms authentication does not enable Client Integration

features. This option, which is found on the Authentication Provider page in SharePoint Central
Administration, must be turned on if you want to use the SharePoint Web services. When this option is
turned off, SharePoint Products and Technologies also turn off support for remote interfaces, such as
Web services.

fbaAuth.Authentication auth =

new

fbaAuth.Authentication();

fbaLists.Lists lists =

new

fbaLists.Lists();

C#

Copy Code

Strona 22 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

Additional Resources

8. Create a CookieContainer collection object for the Authentication class proxy; the authentication cookie

will be stored in this container after calling the Login method.

9. Call the Login method, and check the result from that call, as shown in the following code.

If the Login method succeeds, the proxy for the Authentication Web service has a valid authentication cookie in
its CookieContainer collection. To reuse this cookie, just set the CookieContainer property for the Lists Web
service proxy equal to the CookieContainer property of the Authentication Web service proxy. You can then
make calls to the Lists Web service, and the authentication cookie will be used to authenticate and authorize the
request. That means that when you make a Web service request, the cookie with authenticate and authorize the
request based on the permissions of whatever account was used to create the authentication cookie.

Following is the remainder of the code sample.

This concludes part 2 of this article series.

Next step:

Forms Authentication in SharePoint Products and Technologies (Part 3): Forms Authentication vs.

Windows Authentication

[ http://msdn2.microsoft.com/en-us/library/bb977430(printer).aspx ] .

Dim

auth

As

New

fbaAuth.Authentication()

Dim

lists

As

New

fbaLists.Lists()

Visual Basic

Copy Code

auth.CookieContainer =

new

System.Net.CookieContainer();

auth.AllowAutoRedirect =

true

;

fbaAuth.LoginResult lr = auth.Login(

"myUserName"

,

"myUserPassword"

);

if

(lr.ErrorCode == fbaAuth.LoginErrorCode.NoError)

{

//Now we can talk to the Lists Web service.

}

C#

Copy Code

auth.CookieContainer =

New

System.Net.CookieContainer()

auth.AllowAutoRedirect =

True

Dim

lr

As

fbaAuth.LoginResult = auth.Login(

"myUserName"

, _

"myUserPassword"

)

If

lr.ErrorCode = fbaAuth.LoginErrorCode.NoError

Then

'Now we can talk to the Lists Web service.

End

If

Visual Basic

Copy Code

if

(lr.ErrorCode == fbaAuth.LoginErrorCode.NoError)

{

// Now we can talk to the Lists Web service.

lists.CookieContainer = auth.CookieContainer;
XmlNode xData = lists.GetListCollection();
}

C#

Copy Code

If

lr.ErrorCode = fbaAuth.LoginErrorCode.NoError

Then

' Now we can talk to the Lists Web service.

lists.CookieContainer = auth.CookieContainer

Dim

xData

As

XmlNode = lists.GetListCollection()

End

If

Visual Basic

Copy Code

For more information, see the following resources:

Strona 23 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx

background image

z

Forms Authentication in SharePoint Products and Technologies (Part 1): Introduction

[ http://msdn2.microsoft.com/en-us/library/bb975136(printer).aspx ]

z

Forms Authentication in SharePoint Products and Technologies (Part 3): Forms Authentication vs. Windows
Authentication

[ http://msdn2.microsoft.com/en-us/library/bb977430(printer).aspx ]

z

What Every SharePoint Administrator Needs to Know About Alternate Access Mappings Part 1 of 3

[ http://blogs.msdn.com/sharepoint/archive/2007/03/06/what-every-sharepoint-administrator-needs-to-
know-about-alternate-access-mappings-part-1.aspx ]

z

What Every SharePoint Administrator Needs to Know About Alternate Access Mappings Part 2 of 3

[ http://blogs.msdn.com/sharepoint/archive/2007/03/19/what-every-sharepoint-administrator-needs-to-
know-about-alternate-access-mappings-part-2-of-3.aspx ]

z

What Every SharePoint Administrator Needs to Know About Alternate Access Mappings Part 3 of 3

[ http://blogs.msdn.com/sharepoint/archive/2007/04/18/what-every-sharepoint-administrator-needs-to-
know-about-alternate-access-mappings-part-3-of-3.aspx ]

z

Configuring Multiple Authentication Providers for SharePoint 2007

[ http://blogs.msdn.com/sharepoint/archive/2006/08/16/702010.aspx ]

z

SharePoint Server 2007 Developer Portal

[ http://msdn2.microsoft.com/en-us/office/aa905503.aspx ]

z

How to Use ADFS to Turn MOSS 2007 into a Claims-Aware Application

[ http://blogs.msdn.com/sharepoint/archive/2007/02/15/how-to-use-adfs-to-turn-moss-2007-into-a-
claims-aware-application.aspx ]

z

Plan Authentication Settings for Web Applications in Office SharePoint Server

[ http://technet2.microsoft.com/Office/en-us/library/d3e0e0fc-77b6-4109-87d6-53ad088db01d1033.mspx?
mfr=true ]

z

How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI

[ http://msdn2.microsoft.com/en-

us/library/ms998280(printer).aspx ]

z

How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA

[ http://msdn2.microsoft.com/en-

us/library/ms998283(printer).aspx ]

z

User Security Attributes

[ http://msdn2.microsoft.com/en-us/library/ms677943(printer).aspx ]

z

Office Developer Center

[ http://msdn.microsoft.com/office ]

z

Windows SharePoint Services Developer Center

[ http://msdn.microsoft.com/wss ]

Community Content

Strona 24 z 24

Forms Authentication in SharePoint Products and Technologies (Part 2): Members...

2008-02-22

http://msdn2.microsoft.com/en-us/library/bb975135(printer).aspx


Wyszukiwarka

Podobne podstrony:
Forms Authentication 3 of 3
Forms Authentication 1 of 3
FORMS AUTHENTICATION
abbreviated forms overuse of 6RJE7LHBH7D6MBX3PJCQQESUBGJO72XTEVWOXGA
The Authenticity of Song Performance in Early American Sound Cinema
A Critical Look at the Concept of Authenticity
forms of concentration the landed property in italy
The comparison of two different forms of?vertisement
Forms of Grains
Cancer Proposed Common Cause and Cure for All Forms of Cancer David W Gregg, PhD
Racism, Racial Discrimination, Xenophobia and Related Forms of Intolerance, Follow up and Implementa
A software authentication system for the prevention of computer viruses
LITTLEWOOD Bringing Ritual to Mind psychological fundation of cultural forms by R N McCauley
network forms of organization
0415162866 Routledge On Durkheims Elementary Forms of Religious Life Mar 1998
Victoria Fontan Voices from Post Saddam Iraq, Living with Terrorism, Insurgency, and New Forms of T

więcej podobnych podstron