Authentication and Authorization in the Live Framework

An application or website accessing Live Services on behalf of a user needs to present a credential identifying the user to Live Services and should only be authorized to access those Live Services to which the user has explicitly granted consent.

An application could, of course, show a sign-in dialog to the user requesting the users Live ID and password and use that subsequently to impersonate the user. Social networking sites do this when they ask for user credentials so they can capture social graphs from other services. The problem with this technique is that it creates a massive security hole in that users should only ever present their credentials to the identity service issuing these credentials.

Windows Live provides these capabilities through Windows Live ID the modern incarnation of Microsoft Passport. Windows Live ID provides three services to developers:

A rich client uses Client Authentication to authenticate a user to Live Services and receive an authentication token that can be used in subsequent access to Live Services. The model used in the Live Framework examples is that the application asks for the Live ID and password of the user and then uses these to impersonate the user. This creates the problem of the user providing credentials directly to an application other than Windows Live ID which manages the credentials. The Live Framework team appears to be developing sign-in functionality that will allow an application to display a Windows Live sign-in dialog directly connected to the Windows Live ID and which will return an authentication ticket to the application for subsequent use in accessing Live Services. This authentication ticket is permanent not requiring periodic refresh and, furthermore, does not support the concept of consent. To be fair, this functionality appears to be early in the development phase and will hopefully be made more robust with time.

A website uses Web Authentication to authenticate a user to Live Services and receive a permanent authentication token that uniquely identifies the user. The application can use that token to identify the user in any subsequent visits to the website because the authentication token is permanent. However, this authentication token does not authorize the website to access Live Services on behalf of the user. Consequently, I won’t discuss Web Authentication in this post.

A website uses Delegated Authentication to authenticate a user to Live Services and receive a temporary authentication token, referred to as a consent token, that the website can use to access Live Services on behalf of the user. This access is controlled by the user who must explicitly grant consent to any Live Services the website seeks to access. The user remains in complete control of that consent and can revoke it at any time. Note that the consent token is temporary and can not be used to identify the user once it has expired.

Registering Applications on the Azure Portal

Applications or websites using any of these authentication techniques must first be provisioned and registered for authentication on the Azure Services Developer portal. This process is similar for each of Client Authentication, Web Authentication and Delegated Authentication. Note that although the MSDN documentation for Client Authentication does not rely on the portal, the sample code provided by Microsoft assumes that the application is provisioned similarly to a website using Web Authentication.  Depending on the type of application authentication being provisioned the portal will use or provide some or all of the following information:

  • Application Self Link – the self-link of the installed application in the application developer’s user’s Mesh.
  • Application ID – another unique identifier for the application (similar to 00000000480120F0).
  • Domain – domain of the application website.
  • Return URL – return URI to which the user is returned following authentication.
  • Secret Key – used to encrypt and sign tokens sent by Windows Live ID.

The application developer supplies the Domain and the Return URL while the portal generates the other information.

Client Authentication

Client Authentication uses the Windows Live ID Client 1.0 SDK which can be downloaded here. The installation places the assembly Microsoft.WindowsLive.Id.Client.dll in the following directory:

C:Program FilesCommon FilesMicrosoft SharedWLIDClient

This assembly contains an IdentityManager and an Identity class declared as:

public sealed class IdentityManager {
    // Properties
    public String AppName { get; set; }

    // Methods
    public Identity CreateIdentity();
    public Identity CreateIdentity(String userName);
    public Identity CreateIdentityFromAuthString(String authBlob);
    public static IdentityManager CreateInstance(String appId, String appName);
    public Identity GetIdentityByCId(String cId);

    // Implemented Interfaces and Overridden Members
    protected override void Finalize();
}

and

public class Identity {
    // Properties
    public String cId { get; }
    public Boolean IsAuthenticated { get; }
    public CredentialType SavedCredentials { get; }
    public String UserName { get; }

    // Methods
    public Boolean Authenticate(AuthenticationType authType);
    public Boolean Authenticate();
    public void CloseIdentityHandle();
    public String ExportAuthString();
    public void GetNavigationData(String serviceUrl, String policy, ref String outUrl, ref String postData);
    public String GetTicket(String serviceName, Boolean forceGetFromServer);
    public String GetTicket(String serviceName, String policy, Boolean forceGetFromServer);
    public void OpenAuthenticatedBrowser(String serviceUrl, String policy);

    // Implemented Interfaces and Overridden Members
    protected override void Finalize();
}

Scott Lovegrove and Rong Cao have separately provided examples of these classes being used for user sign-in and access to the Mesh. The following example code is essentially the same as theirs:

IdentityManager identityManager = IdentityManager.CreateInstance("APPLICATION ID",
     "USER-FRIENDLY NAME FOR APPLICATION");
Identity identity = identityManager.CreateIdentity();
if (!identity.IsAuthenticated)
{
    if (identity.Authenticate())
     {
          String userName = identity.UserName;

          String ticket = identity.GetTicket(Constants.CloudEndpoint.AbsoluteUri, "MBI", true);
          LiveItemAccessOptions liveItemAccessOptions = new LiveItemAccessOptions(true);
          LiveOperatingEnvironment liveOperatingEnvironment = new LiveOperatingEnvironment();
          liveOperatingEnvironment.Connect(ticket, AuthenticationTokenType.UserToken,
               Constants.CloudEndpoint, liveItemAccessOptions);

          Mesh mesh = m_liveOperatingEnvironment.Mesh;
          var meshObjectQuery = (from mo in mesh.CreateQuery<MeshObject>()
                                              where mo.Resource.Title == "Magazine"
                                              select mo);

          MeshObject meshObject = meshObjectQuery.FirstOrDefault<MeshObject>();
     }
}

The Identity.Authenticate() method causes a sign-in dialog box to be displayed to the user. The application has no access to this dialog box and consequently no access to the Live ID and password presented as credentials by the user. On successful authentication, the application can generate an authentication ticket and use that in the LiveOperatingEnvironment.Connect() method to connect to the cloud LOE. Since this authentication technique lacks the concept of consent the application has full access to the user’s Mesh.

It appears to be irrelevant currently what the parameters passed to IdentityManager.CreateInstance() actually are. Furthermore, it doesn’t appear to matter whether or not the application has been provisioned for authentication or not. These could be, and in my opinion should be, subject to change. I hope that the user will eventually be able to grant and revoke consent regarding the application’s access to the user’s Mesh.

Delegated Authentication

A Resource Provider, such as Live Services, uses the Live ID Consent Service to manage authorization of third-party websites to resources, such as user profile information, it provides on behalf of the user who owns the information. A User uses the Consent Service to manage the consents allowed to third-party websites. The user can, for example, revoke a previously granted consent. A website can make a consent request of the Consent Service to gain authorization to access information controlled by the Resource Provider but owned by the user.

The Consent Service deals with permissions as combinations of offers and actions. For example, an offer might be News which can be combined with Read, Write and Full actions to create the following permissions: News.Read, News.Write and News.Full. The Consent Service also supports more granular permissions by delegating the management of these to the Resource Provider itself.

Live Services as a Resource Provider

Live Services is a resource provider that makes available the following permissions:

  • Profiles.Read
  • Contacts.Read
  • Contacts.Write
  • News.Read
  • News.Write
  • News.Full
  • LiveMeshFolder.Read
  • LiveMeshFolder.Write
  • LiveMeshFolder.Full
  • <CustomType>.Read
  • <CustomType>.Write
  • <CustomType>.Full

A website using the Live Framework API that needs to access a user’s profile can submit a consent request for Profiles.Read to the Consent Service which will in turn explicitly prompt the user to grant or revoke consent. Absent that permission the website will not be able to access the user’s Profile. Live Services does not support Profiles.Write so no third-party website can successfully issue a Profiles.Write consent request and thereby gain write access to a user’s profile. A website can successfully issue a consent request of News.Write and gain write access to a user’s Live Services news feed.

Live Services supports consent requests for read, write and full access to a user’s Live Mesh folders. Furthermore, it also supports consent requests for read, write and full access to arbitrary mesh objects of a specified resource type – identified as <CustomType> in the list of offerings. For example, if a user has a mesh object of resource type Music a website could successfully issue a consent request of Music.Write if it needed write access to the mesh object to, for example, upload MP3s as media resources to a data feed. The read, write and full offers for LiveMeshFolder are essentially a special case of <CustomType> because LiveMeshFolder is the resource type for root folders on the Live Desktop.

A user can manage permissions by signing into the Consent Service at http://consent.live.com using a Live ID. The Consent Service presents the user with a list of websites along with the permissions each of them has been granted and the expiration dates of the permissions. The user can revoke that access at any time. Note that the Consent Service is still a work in progress so, for example, permissions of <CustomType> are not displayed in the list presented to the user although programmatic access by websites appears to work correctly.

Consent Request

An application issues a consent request by navigating to the consent URI with a query string containing the terms of the consent request. The precise architectural details of the consent request interaction between application and the user is in the Architectural Overview of Delegated Authentication.

Currently, the base of the consent URI is:

https://developer.mesh-ctp.com/web/apps/appconsent.aspx

The query string comprises the following parameters:

  • app – timestamped and signed token containing the application ID issued by the Windows Azure portal.
  • appctx – an application-specific context such as a redirect page following processing of the consent request.
  • appUrl – identifies the installed application in the user’s mesh.
  • in – identifies an individual resource or mesh object for which permission is being requested.
  • pl – URI of the privacy policy for the application .
  • ps – comma-delimited list of permissions being requested, e.g. PS=Profiles.Read,Music.Full.
  • ru – return URI of the active page to which the Consent Service POSTs the consent token.

The user is prompted to sign in to  the Live Services consent request page and asked to confirm the grant or denial of consent to the website for the specified resources. The Consent Service stores the user consents for future use, and it is inserted in the entry for the installed application (website) in the user’s mesh.

Response to Consent Request

After the user has specified the grants and denials for the consent request the consent request page issues a POST to the return URI specified in the RU query string parameter. This POST comprises the following parameters:

  • action – must be delauth indicating the user has completed a successful consent request.
  • appctx – the application-specific context passed into the consent request.
  • ConsentToken – represents the result of the consent request.
  • ResponseCode – documented as 0 for success and 1 for failure.

Note that the example code assumes and research confirms that ResponseCode is RequestApproved for success, not the documented value of 0.

The consent token comprises six ampersand-delimited parts:

  • delt – delegation token used to identify the user whenever the application tries to access a resource.
  • exp – expiration date and time for the delegation token.
  • lid – identifies location of user’s data
  • offer- list of permissions consented to by the user along with individual expiration dates.
  • reft – refresh token used to refresh an expired delegation token.
  • skey – session key used to decrypt Windows Live ID traffic

The delegation token is the most significant part of the consent token because it is used to identify the user to Live Services whenever the website wishes to access any of the resources which the user has consented to the website accessing. Essentially, the delegation token represents the user’s Live ID sign-in and password and can be used in place of them when accessing Live Services. However, a website using the delegation token to represent itself as the user is limited to accessing only those Live Services resources which the user has explicitly granted consent and for which that consent has not been revoked or expired. The delegation token must be stored securely and can be reused until expiration, allowing the website to access resources without the user being present. Note that Microsoft recommends that the entire consent token be stored, not just the delegation token.

Refreshing Consent

The delegation token has a fairly short expiration date as do each of the individual offers inside the consent token. Furthermore, the user can use the Consent Service directly to revoke a previously granted consent without the application being issued a new consent token. The website must be able to handle both expected expiration of individual offer and delegation token consent as well as unexpected consent revocation by the user.

A website can issue a refresh consent request, using HttpWebRequest, when it detects the expiration of the grant of consent in a delegation token or one of the permissions. Refreshing consent happens without the need for user involvement. Otherwise, it is similar to consent request with a specially constructed query string being submitted in a GET to a particular URI. The parameters for a refresh consent request are:

  • app – time-stamped and signed token containing the application ID issued by the Windows Azure portal.
  • ps – comma-delimited list of permissions being requested, e.g. PS=Profiles.Read,Music.Full .
  • reft – refresh token used to refresh an expired delegation token.
  • ru – return URI of the active page to which the Consent Service POSTs the consent token.

The Consent Service responds to a refresh consent request with a JSON string containing either a new ConsentToken or an error message.

Implementing Delegated Authentication

An implementation of Delegated Authentication must do the following:

  • create the query string containing the consent request.
  • process the returned consent token.
  • create the query string containing the consent refresh request.

Microsoft has provided a sample website demonstrating delegated authentication in various languages. This website contains a file, WindowsLiveLogin.cs, containing classes that implement these three steps alleviating the need for the developer to implement them. The source code appears intimidating, being more than thirty pages long, but it is in reality a heavily commented implementation of the three steps. Hopefully, the classes in WindowsLiveLogin.cs will be added formally to the Live Framework API at some point in the future.

On successfully completion of a consent request WindowsLiveLogin.cs makes available to the website a delegation token which the website can then use to gain consent-controlled access to the user’s Mesh as follows:

LiveOperatingEnvironment liveOperatingEnvironment = new LiveOperatingEnvironment();
String delegationToken = … // retrieved from WindowsLiveLogin.cs

LiveItemAccessOptions liveItemAccessOptions = new LiveItemAccessOptions(true);
liveOperatingEnvironment.Connect(delegationToken, AuthenticationTokenType.DelegatedAuthToken,
     Constants.CloudEndpoint, liveItemAccessOptions);

Mesh mesh = m_liveOperatingEnvironment.Mesh;
var meshObjectQuery = (from mo in mesh.CreateQuery<MeshObject>()
                                  where mo.Resource.Type == "Music"
                                  select mo);

MeshObject meshObject = meshObjectQuery.FirstOrDefault<MeshObject>();

This can be compared with the earlier example for Client Authentication. An obvious difference is that in the LiveOperatingEnvironment.Connect() method Client Authentication uses AuthenticationTokenType.UserToken while Delegated Authentication uses AuthenticationTokenType.DelegatedAuthToken.

The Live Framework team have published two blog posts which describe Delegated Authentication and the sample code in great detail. I had no trouble following their directions and getting the sample code to work as advertised. The posts are Connecting Your Web Site to the Live Framework (i.e. Using Delegated Auth) and Delegated Authentication, Part II: Managing Tokens.

UPDATE 3/24/2009

Arash Ghanaie-Sichanie does a live demo of Delegated Authentication about 60 minutes into his Mix 2009 presentation on Mesh-Enabled Web Applications.

UPDATE 3/25/2009

Jorgen Thelin has a good presentation on Web Authentication and Delegated Authentication at Mix 2009. He also demonstrates the recently-announced customization of the Live ID sign-in screen that James Senior discusses here.

UPDATE 5/5/2009

I have a more recent post showing on Using Delegated Authentication to Access LiveFX from Windows Azure.

About Neil Mackenzie

Cloud Solutions Architect. Microsoft
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s