A core part of Microsoft.NET is the windows identity
foundation (WIF). In essence, WIF enables .NET developers to externalize
identity and authentication logic from their application. This means as
your authentication models change, your application doesn't have to
change. Also, to your application an identity is an "identity".
Therefore, it doesn't matter if it came from a windows identity, a Live
ID identity, or anything else.
WIF revolves around the
concept of claims based identity. Claims based identity is a very simple
idea and revolves around some simple concepts such as claims, tokens,
and identity providers.
For a moment stop
thinking about technology and think of what an identity really means.
Let's say you met me at the conference before. Then, one fine day, you
find me homeless on the streets of San Francisco begging for donuts. You
would probably look at me and try to recognize some of my features that
you think I cannot fake and find features that you can trust such as my
eyes, my height, or voice, and I'll probably be talking about
SharePoint. These features will allow you to establish an identity of me
in your mind. Given that identity you will probably give me $5.00 to go
buy donuts. However, if with that identity I requested to see your
driver's license you would probably turn me down. Unless perhaps, I
provided additional claims about myself that you can trust, like my
proving that I'm really an undercover police officer.
At that point, I would be
establishing my identity with you by providing claims about myself in a
way that you can trust those claims. Also, as the needs of my access
change, you can query me for additional claims. Therefore, my identity
can be augmented as I work through your system; something you could not
do with a pure authentication only model.
In this case, however,
you are requesting the claims and you yourself are validating the
claims. Let's think of an example where the party validating the claims
is different from the party requesting the claims.
Say I was caught speeding
on some freeway in California. I don't live in California, but chances
are if I presented my home state's drivers license to the police
officer, that is an identity that the police officer trusts. In other
words, the California police trusts the issuing authority of my driver's
license. In this scenario, as long as the California police officer is
convinced that my claims are valid and untampered, my identity can be
established in the mind of the California police officer. This is an
example where the relying party (California policeman), relied on an
external secure token service (my home state driver's license issuing
authority) to provide the user (me) with some service.
Therefore, in terms of
computers, as long as you can transfer an untamperable token with one or
more claims about who you are, service providers will grant you the
necessary access. Also, within the same application as you need further
levels of elevated access you can simply continue to provide more claims
about who you are. These claims can represent anything about a user.
But, if in fact the server requested the exact age of the user then a
new claim can be presented, perhaps from the driver's license issuing
authority. Therefore, claims can represent pretty much any information
about the user and applications can continue to ask further claims,
without worrying where the claims are coming from—as long as they are
not tampered.
In a computer system how
exactly does this work? Typically, when a user makes a request to a
server, and if the server is protected behind some sort of
authentication, the user through their web browser or another client
would ask an Security Token Service (STS) for a token containing claims
for this user. Such a request is made using the standard protocol
WS-Trust. This request is authenticated in some manner such as providing
a kerberos ticket or maybe a password. Once such authentication has
been done by the STS, it would then generate the token and return it to
the requestor. The requester can then present that token, usually
encoded as Security Assertion Markup Language (SAML) and present it to
the service provider server.
Imagine if your
SharePoint site was protected behind windows live ID. As the user, you
would try accessing the SharePoint site; SharePoint would inform your
browser that it requires a certain kind of token and where you can get
such a token from. You would then reach out to the STS of windows live
ID and then present that token to SharePoint in order to be able to gain
access to the SharePoint site.
Now let's say your
SharePoint site could accept two kinds of claims. It could accept the
windows live ID or it could accept a windows identity. In either case,
you would reach out to the appropriate STS and provide SharePoint with
the appropriate identity. What is most interesting is that the actual
application, SharePoint itself, doesn't really care where you got the
token from as long as you have a valid token that SharePoint trusts.
This means that one single web site can now support multiple
authentication mechanisms; there is no difference between authentication
mechanisms, so things such as client integration will continue to work
no matter what kind of authentication you're using.
Compare this with what you used
to have to do in SharePoint 2007. In SharePoint 2007, in order to
support multiple authentications, you had to extend your web application
on multiple web sites. Then each one of those applications could be
configured to use a different kind of authentication mechanism. This
meant that you had multiple URLs for the same content which caused a lot
of confusion. Also, this meant that depending upon the kind of
authentication you're using certain features did not work.
Another corollary of
this problem was that sometimes you would have the same user accessing a
system both from inside the firewall and outside the firewall over
different kind of authentication mechanisms. To SharePoint in SharePoint
2007, this would appear as two separate identities. This was a huge
functionality problem. Claims based identity also allows you to do
identity reconciliation. However, in SharePoint 2010, identity
reconciliation is something that is not built as a part of SharePoint.
You could perform identity reconciliation outside of SharePoint in the
claims based identity framework.
1. Claims Based Identity in SharePoint
With the basic theory of
claims based identity behind you, now let's see how claims based
identity works inside of SharePoint. Deep inside the depths of the
SharePoint object model, any authenticiable entity in SharePoint is
represented with the SPPrincipal object. The two classes that inherit
from SPPrincipal are SPGroup and SPUser. At the end of the day, as long
as either a windows identity or a claims based identity can be
normalized to a SPPrincipal, the rest of the object model doesn't have
to worry about the kind of identity you're using.
When you create a new web
application under the authentication section, you can pick from either
claims based authentication or classic mode authentication. This can be
seen in Figure 1.
Assuming that you have
picked and configured claims based authentication in your web
application, accessing a protected resource within SharePoint is
illustrated in Figure 2.
The steps being followed in sequence are described as follows.
Resource request:
It all starts at the resource request. The user makes a request through
a client. The client can be a web browser, or a thick client, such as
the office client. A resource request can be as simple as a "GET"
request, asking for something like a Word document for example.
Authenticate redirect:
SharePoint tells the user that the user is not yet authorized to get
the resource, but replies with a URL that the client can go to in order
to authenticate.
Authenticate request: At this point, the user makes an authentication request to the separate identity provider security token service (IP-STS).
Security token:
Once you have provided your credentials, the IP-STS will validate you
against the internal store. The internal store can be Active Directory,
ASP.NET Membership Provider database, Live ID, or anything else.
Assuming that your credentials are valid, you will then be provided with
a security token.
Service token request: With a security token provided to the client, the client then provides that token to the SharePoint STS.
Security token response:
The SharePoint STS decides if it wishes to trust the provided security
token. Assuming that a trust relationship has previously been defined
between the SharePoint STS and the IP-STS, SharePoint internally will
talk to a number of other claims providers and see if there are any
additional claims that can be added to the trusted security token. For
example, if you have logged in as "smalik", a claims provider to my ERP
system may authorize me as a person who has the ability to approve
invoices and may add that claim into my token. At this point, the token
is repackaged, and a new SAML token is issued by SharePoint, to be used
within SharePoint, which is the security token response. This is also
sometimes referred to as augmented claims token.
Request resource with service token:
Finally, a request is made with the final package and augmented
security token response and a resource request is repeated with the
security token response. At this point, the request is converted into an
SPUser object and is passed on to the SharePoint authorization
infrastructure.
As you can see, all the
complexity of actually identifying the user is completely separate from
the authorization portion. This means that you can have multiple
identity providers, and these multiple identity providers can
potentially also be in different organizations. As long as they trust
each other, this SAML-based token can be passed across firewalls or even
across the Internet. This means that you can have multiple hop of the
user's identity all across the Internet. This user's identity can also
be used to authenticate to systems such as web services, and the user
can use his own organization's identity to authenticate with any other
organization's system as long as a trust relationship has previously
been established between the two organizations.
All of these are scenarios were previously somewhere between impossible and very difficult to implement in SharePoint 2007.
Next, let's see the specific
steps you need to take to enable claims based identity on a SharePoint
site. You will create a web application in the SharePoint installation
that uses two kinds of authentication. One is based on windows
authentication and the second is based on forms based authentication.
Both of these authentications are normalized to an SPUser identity as I
described earlier, but this is done using claims based authentication.
The
first thing you need is a membership provider. You can use any
membership provider as long as it implements the ValidateUser() method,
because the claims based infrastructure in SharePoint relies on this
method to tie in an ASP.NET identity with a claims based identity. The
membership provider I intend to use in this example is the
AspNetSqlMembershipProvider, which is an out of the box membership
provider with .NET 2.0. For this membership provider, you need a
membership provider database. Therefore, create that ASP.NET DB
membership provider database by running the following command:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe.
Running
this command will pop open a wizard-like interface which will guide you
through the steps of creating such a database on a SQL server. Choose
to use SQL authentication over windows authentication because the
SharePoint installation will also need to talk to the server, and the
various configuration changes are a lot easier if you choose to use SQL
authentication over windows authentication.
Once
you have created such a database, the next thing you need to do is to
populate this database with some users. Therefore, in Visual Studio
create a blank ASP.NET application and add a connection string section,
as shown in Listing 1. Note you need to specify the proper user credentials in the connection string.
Example 1. The ConnectionStrings Section for the ASP.NET web.config
<connectionStrings> <connectionStrings> <remove name="LocalSqlServer"/> <add connectionString="Data Source=SP2010;Initial Catalog=aspnetdb;User ID=sa;Password=p@ssword1" name="LocalSqlServer"/> </connectionStrings>
|
You
can populate the users inside the membership provider using numerous
ways. The simplest way to do this is to launch the web site
administration tool. You can launch the tools by visiting the project
menu and choosing ASP.NET configuration. Be careful as the project menu
is available only when you have an ASPX open and not when you have the
web.config open.
When
the ASP.NET website administration tool opens, click the security link,
and click "Select Authentication Type" to choose to authenticate users
from the Internet.
Next, click the create user link and add a new user, as shown in Figure 3.
Your
database is now set up. Next, you need to provision a new web
application from central administration that will use claims based
authentication. In order to do so, visit central administration and
under applications settings\manage web applications, choose to create a
new web application. If you need to switch the authentication type on an
existing web application, you may follow the instructions here http://blah.winsmarts.com/2010-3-Enable_Claims_based_Auth_on_a_SP2010_website,_after_it_has_been_provisioned.aspx.
As you create a new web application, choose to use claims based
authentication instead of classic mode authentication. Choosing claims
based authentication will make a new section visible that will allow you
to pick the different authentications you wish to use within this web
application. Choose to configure it, as shown in Figure 4.
Your
database setup and your web application are now set up. (I created my
web application on Port 80.) Next, you need to make three web.config
changes within SharePoint. The first two changes configure the
membership provider properly inside the port 80 and central
administration web sites. Therefore, open the web.config for central
administration and for your port 80 web application add the same
ConnectionStrings section you see in Listing 1 into these web.configs.
The
other web.config you need to change is for the SharePoint STS. This
needs to know about the membership provider as well, so open the
web.config for the SharePoint STS, which you will find at
{SharePointRoot}\WebServices\Root\web.config, and add the same
ConnectionStrings section to this web.config. Now, scroll to the top of
this web.config and look for the system.web\membership section. Note
that this web at config chooses to clear all membership providers
defined in the machine.config. Over here you need to read the
AspNetSqlMembershipProvider. This can be seen in Listing 2.
Example 2. The Entry for the AspNetSqlMembershipProvider
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
|
You're
all set, with one exception. You haven't yet created a site collection.
In your port 80 web application, create a site collection and mark two
different site collection administrators, one coming from the membership
provider and another using windows identity. This can be seen in Figure 5.
Perfect! Now open your web
browser and visit your port 80 web application. Note that you are
prompted to pick the authentication mechanism in a dropdown, as shown in
Figure 6.
Sign in using windows
authentication. Note that the browser automatically signs you in using
your windows identity. Now choose to sign out (not just close the
browser). You can sign out by clicking your name on the right-hand top
corner in your browser and choosing the sign out menu item.
Next, try and
login using forms authentication. When you login using forms
authentication, you would note that your forms based identity is
available on the same site, and the same URL as you had logged in using
windows authentication earlier. Therefore, all SPPrincipals are
available in all zones. While you're signed in, create a document
library and put in a sample document in that document library. I created
a document at http://sp2010/My%20Documents/Test%20Document.docx.
Next, sign out once more and
start Word 2010. Choose to open a new document and in the file name type
http://sp2010/My%20Documents/Test%20Document.docx. Note that Word 2010
prompts you with a claims based identity login dialog box, as shown in Figure 7.
Sign in using either forms
based identity or windows based identity and Word will be able to open
the document using your claims based identity. Therefore, you can see
that the experience across different kinds of clients does not change no
matter what kind of authentication you're using.
When using FBA in SharePoint 2010, you should keep the following in mind:
FBA identities are now claims based identity instead of generic ASP.NET identities.
It
is the STS that calls the membership provider to validate users and
issues claims tokens. This is done using standard hooks in the windows
identity framework.
ValidateUser() must be implemented in the membership providers.
Roles are also converted to claims and can be used as SPUsers inside SharePoint.
All SPPrincipals are available in all zones.