web services and identity for visual studio 2010...

51
Hands-On Lab Web Services and Identity for Visual Studio 2010 Developers Lab version: 1.0.0 Last updated: 1/21/2011

Upload: others

Post on 15-Oct-2019

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Hands-On Lab

Web Services and Identity for Visual Studio 2010 Developers

Lab version: 1.0.0 Last updated: 1/21/2011

Page 2: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Contents

OVERVIEW ................................................................................................................................................... 3

EXERCISE 1: USING WINDOWS IDENTITY FOUNDATION TO HANDLE AUTHENTICATION AND

AUTHORIZATION IN A WCF SERVICE ...................................................................................................... 7 Task 1 - Reviewing the Begin Solution .................................................................................................. 7

Task 2 - Using Windows Identity Foundation to Authenticate Calls to the Service .............................. 9

Task 3 - Using the Service.................................................................................................................... 17

Exercise 1: Verification ........................................................................................................................ 21

Exercise 1: Summary ............................................................................................................................... 24

EXERCISE 2: ACCEPTING TOKENS FROM AN ACTIVE DIRECTORY FEDERATION SERVICES

(ADFS) STS ................................................................................................................................................ 24 Task 1 - Modifying the Service to Accept Tokens Issued by an STS Published via Active Directory

Federation Services (ADFS) ................................................................................................................ 25

Task 2 - Modifying the Client in Order to Secure Calls to the Service via Issued Token ..................... 34

Task 3 - Using Claims for Authorizing the Service Call ........................................................................ 35

Exercise 2: Verification ........................................................................................................................ 38

Exercise 2: Summary ............................................................................................................................... 39

EXERCISE 3: INVOKING A WCF SERVICE ON THE BACKEND VIA DELEGATED ACCESS ............. 40 Task 1 - Opening the Solution ............................................................................................................. 41

Task 2 - Adding a Reference to the Backend Service .......................................................................... 43

Task 3 - Calling the Backend Service ................................................................................................... 46

Exercise 3: Verification ........................................................................................................................ 48

Exercise 3: Summary ............................................................................................................................... 51

SUMMARY .................................................................................................................................................. 51

Page 3: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Overview

Security and identity management are among the most critical aspects of any SOA and distributed

systems in general. Since its introduction in version 3.0 of the .NET Framework, WCF provided the

necessary expressive power for taking advantage of WS-Security, WS-Trust and all the standard

mechanisms which help you to develop and consume web services in interoperable manner.

Today Windows Identity Foundation (WIF), formerly known as Geneva, brings the approach further,

abstracting away most of the complexity for application developer and providing a clear extensibility

model for security developers. By introducing a unified approach to claims-based identity which applies

both to WCF and ASP.NET, Windows Identity Foundation makes claims a first-class citizen in the .NET

framework; furthermore, the enhancements to Visual Studio integration guarantee that the use of

advanced identity capabilities will easily blend within the familiar development practices of Visual Studio

users.

During this Hands-on lab you will learn how to take advantage of the new model, classes and tools that

constitute Windows Identity Foundation. Some tasks will show how to solve problems you are already

familiar with, demonstrating the improvements in respect to the WCF-only model; some other task will

show how to easily solve problems that in the past required very complex solutions, and that are now

within reach of any developer. More specifically, you will learn how to:

Use the Windows Identity Foundation object model to authenticate and authorize web service

calls

Take advantage of production STSes for externalizing authentication and obtaining claims about

the user

Authorize access to services by imposing conditions on incoming claims

[Optional] Leverage the .NET Access Control Service for handling claim transformations

Handle delegation scenarios

Windows Identity Foundation can do much more than what we cover in this lab: we hope that the skills

you will learn here will help you in your further explorations of identity development.

Objectives

In this Hands-On Lab, you will learn how to:

Authenticate and authorize web service calls

Trust tokens from a production STS

Authorize access to services by imposing conditions on incoming claims

Page 4: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Obtain delegated tokens and authorize calls protected by delegated tokens

System Requirements

You must have the following items to complete this lab:

Microsoft® Windows® Vista SP2 (32-bits or 64-bits) , Microsoft® Windows Server 2008 SP2 (32-

bit or 64-bit), Microsoft® Windows Server 2008 R2, Microsoft® Windows® 7 RTM (32-bits or 64-

bits)

Microsoft® Internet Information Services (IIS) 7.0

Windows Feature WCF HTTP Activation

Microsoft® .NET Framework 4.0

Microsoft® Visual Studio 2010

Microsoft® Windows Identity Foundation Runtime

Microsoft® Windows Identity Foundation SDK 4.0

Setup

For convenience, much of the code used in this hands-on lab is available as Visual Studio code snippets.

To check the prerequisites of the lab and install the code snippets:

1. Open a Windows Explorer window and browse to the lab’s Source\Setup folder.

2. Double-click the Dependencies.dep file in this folder to launch the Dependency Checker tool

and install any missing prerequisites and the Visual Studio code snippets.

3. If the User Account Control dialog is shown, confirm the action to proceed.

Note: This process may require elevation. The .dep extension is associated with the

Dependency Checker tool during its installation. For additional information about the setup

procedure and how to install the Dependency Checker tool, refer to the Setup.docx document

in the Assets folder of the training kit.

4. After the code snippets installation completes, the setup script will proceed with the certificates

installation. Press Y if you want to continue with the required certificates installation.

Note: Next, the setup script will proceed by replacing any existing localhost certificate with a

new one. If you already have a "localhost" certificate needed by another application, ensure to

make a backup copy before proceeding with the lab's certificates installation.

Page 5: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 1

Certificates installation finished

Note: If you are running Windows 7 or Windows 2008 R2 you might not see this window.

5. When finished, press any key to close the setup console.

Note: In addition to the setup script inside the

%YourInstallationFolder%\Labs\WebServicesAndIdentity\Source\Setup folder, there is a

Cleanup.cmd file you can use to uninstall all the code snippets installed by the SetupLab.cmd script.

Exercises

The following exercises make up this Hands-On Lab:

1. Using Windows Identity Foundation to Handle Authentication and Authorization in a WCF

Service

2. Accepting Tokens from an Active Directory Federation Services (ADFS) STS

3. Invoking a WCF Service on the Backend via Delegated Access

Note: Each exercise is accompanied by a starting solution. These solutions are missing some code

sections that are completed during each exercise and therefore will not work if executed directly.

Page 6: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Inside each exercise folder, you will also find an end folder with the solution that you should obtain

after completing the exercise. You can use it as a guide if you need additional help working through

the exercises.

Using the Code Snippets

With code snippets, you have all the code you need at your fingertips. The lab document will tell you

exactly when you can use them. For example,

1. Paste the following snippet at the end of the GetForecast method to return the image from the

service.

(Code Snippet – Web Services and Identity Lab - Ex03 Returning the Satellite Image)

C#

return new WeatherResult

{

Forecast = forecast,

SatelliteImage = image

};

To add this code snippet in Visual Studio, you simply place the cursor where you would like the code to

be inserted, start typing the snippet name, in this case

WebServicesAndIdentityLabEx03ReturningTheSatelliteImage, watch as Intellisense picks up the snippet

name, and hit the TAB key twice once the snippet you want is selected. The code will be inserted at the

cursor location.

To insert a code snippet using the mouse rather than the keyboard (i.e. for Web.config file or any other

XML document), right-click where you want the code snippet to be inserted, select Insert Snippet

followed by My Code Snippets and then select the relevant snippet.

To learn more about Visual Studio IntelliSense Code Snippets, including how to create your own, please

see http://msdn.microsoft.com/en-us/library/ms165392.aspx.

Estimated time to complete this lab: 60 minutes.

Page 7: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Exercise 1: Using Windows Identity

Foundation to Handle Authentication and

Authorization in a WCF Service

In this first exercise, you will gain familiarity with the way in which Windows Identity Foundation (WIF)

handles authentication and authorization for web service calls. You may have used WCF classes in the

past to obtain similar results: the Windows Identity Foundation (WIF) makes things simpler, and while it

handles the same concepts (tokens, claims), it offers a more task-based approach.

Note that, for the sake of clarity, the web service in this exercise does not take advantage of issued

tokens or claims: we secure the call with username and password so that we can illustrate differences

between WCF’s and Windows Identity Foundation’s object model as crisply as possible. All subsequent

exercises will instead take advantage of issued tokens and claims.

Figure 2

In this exercise the client invokes the service using username & password credentials. The credentials are

verified in a custom token handler, while the authorization policies (based on the name of the caller) are

enforced via a custom implementation of ClaimsAuthorizationManager

Task 1 - Reviewing the Begin Solution

1. Open Microsoft Visual Studio 2010 with administrator privileges. From Start | All Programs |

Microsoft Visual Studio 2010, right-click Microsoft Visual Studio 2010 and choose Run as

administrator.

2. Open the WeatherStation.sln solution file located in the

%YourInstallationFolder%\Labs\WebServicesAndIdentity\Source\Ex1-

SecuringWebService\Begin folder.

Page 8: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Note: Ensure that the WeatherStationService application of the newly created service has

anonymous authentication enabled. To do this, go to IIS Manager and browse for %machine

name% | Sites | Default Web Site | WeatherStationServiceEx01, select the application node

in the Connections tree view and then double-click Authentication. Locate the Anonymous

Authentication item in the list and check its status. To enable anonymous authentication,

right-click its entry in the list view and select Enable.

3. Review the initial solution.

Page 9: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 3

Exercise 1 begin solution

Note: This solution represents a classic WCF web service-WinForm web service client scenario,

implemented using Visual Studio 2010 templates defaults (hence just with the default security

settings of wsHttpBinding).

The WeatherStationClient project is a WinForms application that uses the

WeatherStationService WCF service to retrieve the forecast for the next 3 or 10 days and

displays the results on the UI. In its initial state, the client is not wired up to the service: in this

exercise we will add the necessary invocation code and secure it with username/password

credentials. On the service side, we will authenticate the calls based on those credentials and

will handle authorization according to the individual users.

Task 2 - Using Windows Identity Foundation to Authenticate Calls to the Service

1. Right-click the http://localhost/WeatherStationServiceEx01 project and select Add Reference.

2. Select the Microsoft.IdentityModel assembly in the .NET tab.

Page 10: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 4

Adding a reference to Microsoft.IdentityModel

Note: If you did not find the Microsoft.IdentityModel.dll assembly on the Add Reference

dialog, you can add the reference including the following line in the

configuration/system.web/compilation/assemblies section of the Web.config file:

<add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31BF3856AD364E35" />

3. Right-click the App_Code folder in the http://localhost/WeatherStationServiceEx01 project

and select Add New Item.

4. Create a new Class and name it CustomUserNameSecurityTokenHandler.cs

5. Replace the content of the new class with the following code to validate the user credentials in

the issued token and assign the appropriate roles for each valid user.

(Code Snippet – Web Services And Identity Lab - Ex01 CustomUserNameSecurityTokenHandler)

C#

using System;

using System.IdentityModel.Tokens;

Page 11: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

using Microsoft.IdentityModel.Claims;

using Microsoft.IdentityModel.Protocols.WSIdentity;

using Microsoft.IdentityModel.Tokens;

class CustomUserNameSecurityTokenHandler : UserNameSecurityTokenHandler

{

public override bool CanValidateToken

{

get

{

return true;

}

}

public override ClaimsIdentityCollection ValidateToken(SecurityToken

token)

{

UserNameSecurityToken usernameToken = token as UserNameSecurityToken;

if (usernameToken == null)

{

throw new ArgumentException("usernameToken", "The security token

is not a valid username security token.");

}

string username = usernameToken.UserName;

string password = usernameToken.Password;

if (("paul" == username && "p@ssw0rd" == password) || ("john" ==

username && "p@ssw0rd" == password))

{

IClaimsIdentity identity = new ClaimsIdentity();

identity.Claims.Add(new Claim(WSIdentityConstants.ClaimTypes.Name,

username));

return new ClaimsIdentityCollection(new IClaimsIdentity[] {

identity });

}

throw new InvalidOperationException("The username/password is

incorrect");

}

}

Note: If you have custom credential verification logic you want to use for authenticating calls,

Windows Identity Foundation offers you a mechanism for weaving it in the processing

pipeline. The SecurityTokenHandler defines an interface for plugging custom token handling

functionality, which you can use for controlling the credential verification process. Deriving

Page 12: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

your own class from SecurityTokenHandler you can add functionality to serialize, de-serialize,

authenticate and create specific kinds of token. In our example, the

CustomUserNameSecurityTokenHandler class derives from UserNameSecurityTokenHandler

that handles standardized WS-Security UsernameTokens. The key method is ValidateToken:

here we perform a simple check against hardcoded values.

6. Now that we took care of the authentication part, we need to think about authorization. We are

going to take advantage of MyClaimsAuthorizationManager, a class provided with the

Windows Identity Federation SDK samples that allows you to express some simple condition on

the incoming claims that must be satisfied in order to gain access to a resource. Right-click the

App_Code folder of the http://localhost/WeatherStationServiceEx01 project and select Add

Existing Item.

Note: Windows Identity Foundation is not tied to a specific authorization engine: rather, it

offers extensibility points that you can leverage for executing your custom authorization code

within the invocation processing pipeline. The mechanism is somewhat similar to what we

have seen in the authentication steps: you derive your own implementation from the

ClaimsAuthorizationManager class, where you will use the CheckAccess method to verify that

the incoming claims satisfy the conditions assigned to the resource being invoked. Once your

implementation of ClaimsAuthorizationManager is included in the pipeline (via config),

returning “false” from CheckAccess will have the effect of stopping the call. Normally the

authorization conditions are assigned to resources via external files, such as the application

config, so that administrators are able to modify them without altering the application

codebase. Furthermore, you can expect developers to assign conditions via Code Access

Security style calls (i.e. decorating via attributes and so on). Both capabilities will require some

coding support. Seasoned WCF developers will compare ClaimsAuthorizationManager with

ServiceAuthorizationManager: while the two can be used for similar purposes, it should be

noted that ClaimsAuthorizationManager offers a simpler object model that abstracts away

many details of the actual call mechanics.

7. Select all the content in the

%YourInstallationtFolder%\Labs\WebServicesAndIdentity\Source\Assets\ClaimsAuthorizatio

nManager folder and click Add.

Page 13: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 5

ClaimsAuthorizationManager files

8. Open the Web.config file of the http://localhost/WeatherStationServiceEx01 project.

9. Register the microsoft.IdentityModel section. Inside the configSections element add the

following (shown in bold). If the configSections section does not exist, you should add it inside

the configuration element.

(Code Snippet – Web Services And Identity Lab - Ex01 microsoft.IdentityModel section)

XML

<configuration>

<configSections>

...

<section name="microsoft.identityModel"

type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection,

Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31bf3856ad364e35" />

</configSections>

...

</configuration>

10. Add the following settings for the microsoft.identityModel section just before closing the

configuration section.

Page 14: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

(Code Snippet – Web Services And Identity Lab - Ex01 microsoft.IdentityModel settings)

XML

...

<microsoft.identityModel>

<service>

<securityTokenHandlers>

<remove

type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler,

Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31BF3856AD364E35"/>

<add type="CustomUserNameSecurityTokenHandler, App_Code"/>

</securityTokenHandlers>

</service>

</microsoft.identityModel>

</configuration>

Note: The microsoft.identityModel element is the area of the application config that you can

use to enable Windows Identity Foundation and drive its behavior. In the last step, we placed

our custom username token handler in the handler’s collection. Next, we will add our

implementation of ClaimsAuthorizationManager to the pipeline.

11. Add the following setting to configure the ClaimsAuthorizationManager inside

microsoft.identityModel/service.

(Code Snippet – Web Services And Identity Lab - Ex01 ClaimsAuthorizationManager)

XML

...

<microsoft.identityModel>

<service>

<securityTokenHandlers>

<remove

type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler,

Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31BF3856AD364E35"/>

<add type="CustomUserNameSecurityTokenHandler, App_Code"/>

</securityTokenHandlers>

<claimsAuthorizationManager

type="ClaimsBasedAuthorization.MyClaimsAuthorizationManager">

<policy

resource="https://localhost/WeatherStationServiceEx01/Service.svc"

action="http://tempuri.org/IService/GetThreeDaysForecast">

<or>

Page 15: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

<claim

claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"

claimValue="paul"/>

<claim

claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"

claimValue="john"/>

</or>

</policy>

<policy

resource="https://localhost/WeatherStationServiceEx01/Service.svc"

action="http://tempuri.org/IService/GetTenDaysForecast">

<claim

claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"

claimValue="paul"/>

</policy>

</claimsAuthorizationManager>

</service>

</microsoft.identityModel>

</configuration>

Note: The MyClaimsAuthorizationManager sample defines a very rudimentary but effective

syntax for expressing constraints. In the basic case, given a certain service and associated

SOAPAction (resource and action in the schema, respectively), a user can invoke the

corresponding method of the web service if and only if he presents an instance of a given claim

type with the requested value. Conditions in this format can be combined via boolean

operators to form composite authorization criteria. In this exercise, we do not really receive

claims from an STS. However, we can consider the username as a claim and assign our

authorization conditions on a per-user basis.

12. Add the following bindings section under system.serviceModel to specify the usage of WS-

Security UsernameToken for client credentials.

(Code Snippet – Web Services And Identity Lab - Ex01 UsernameBinding)

XML

<system.serviceModel>

<bindings>

<wsHttpBinding>

<binding name="UsernameBinding">

<security mode="TransportWithMessageCredential">

<message clientCredentialType="UserName"/>

</security>

</binding>

</wsHttpBinding>

</bindings>

Page 16: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

<behaviors>

...

</system.serviceModel>

Add the following services element to configure that the service endpoint uses the binding

defined on the previous step.

(Code Snippet – Web Services And Identity Lab - Ex01 Endpoint Configuration)

XML

<system.serviceModel>

<services>

<service name="WeatherStationServiceEx01.Service">

<!-- Service Endpoints -->

<endpoint address="" binding="wsHttpBinding"

bindingConfiguration="UsernameBinding"

contract="WeatherStationServiceEx01.IService"/>

</service>

</services>

<bindings>

...

</bindings>

...

</system.serviceModel>

Note: For what concerns the mechanics of the web service call, this remains a WCF service.

Hence, everything you know about bindings remains valid. Here we simply made sure that we

use username and password credential types.

13. Add the following service extension inside the system.serviceModel element.

(Code Snippet – Web Services And Identity Lab - Ex01 Service extensions)

XML

<system.serviceModel>

...

<extensions>

<behaviorExtensions>

<!-- This behavior extension will enable the service host to be Claims

aware -->

<add name="federatedServiceHostConfiguration"

type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtens

ionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31bf3856ad364e35"/>

</behaviorExtensions>

Page 17: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

</extensions>

</system.serviceModel>

14. Add the federation extension under the

system.serviceModel/behaviors/serviceBehaviors/behavior.

XML

<system.serviceModel>

...

<behaviors>

<serviceBehaviors>

<behavior>

<federatedServiceHostConfiguration/>

<!-- To avoid disclosing metadata information, set the value below to

false and remove the metadata endpoint above before deployment -->

<serviceMetadata httpGetEnabled="true"/>

<!-- To receive exception details in faults for debugging purposes,

set the value below to true. Set to false before deployment to avoid

disclosing exception information -->

<serviceDebug includeExceptionDetailInFaults="false"/>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

Note: The ConfigureServiceHostBehaviorExtensionElement behavior extension is what

enables the Windows Identity Foundation pipeline in front of the service. There are various

alternative ways of achieving the same result, from using a dedicated factory to assigning it

directly via code when handling hosts and channels programmatically.

15. Build the solution.

Task 3 - Using the Service

1. Add a reference to the service in the WeatherStationClient application. To do this, right-click

the WeatherStationClient project and select Add Service Reference.

2. In the Add Service Reference dialog, click Discover.

3. Select the WeatherStationServiceEx01/Service.svc and click OK.

Page 18: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 6

Selecting the service

4. Open the app.config file of the WeatherStationClient project and find the endpoint element

under system.serviceModel/client.

5. Update the address attribute to use https and localhost instead of the machine name

(address="https://localhost/WeatherStationServiceEx01/Service.svc").

XML

<configuration>

<system.serviceModel>

<bindings>

...

</bindings>

<client>

<endpoint

address="https://localhost/WeatherStationServiceEx01/Service.svc"

binding="wsHttpBinding"

bindingConfiguration="WSHttpBinding_IService"

Page 19: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

contract="ServiceReference1.IService"

name="WSHttpBinding_IService" />

</client>

</system.serviceModel>

</configuration>

6. Open the ForecastForm.cs code behind.

7. Add the following using statements.

(Code Snippet – Web Services And Identity Lab - Ex01 ForecastForm Usings)

C#

using System.Drawing;

using System.ServiceModel.Security;

using WeatherStationClient.Properties;

using WeatherStationClient.ServiceReference1;

8. Create a DisplayForecast method to receive the forecast for the next days and display the

results on the UI. To do this, add the following function at the end of the ForecastForm class.

(Code Snippet – Web Services And Identity Lab - Ex01 DisplayForecast)

C#

private void DisplayForecast(Weather[] weather)

{

this.forecastPanel.Controls.Clear();

for (int i = 0; i < weather.Length; i++)

{

PictureBox pic = new PictureBox();

GroupBox box = new GroupBox();

box.Text = string.Format(

CultureInfo.CurrentCulture,

"{0:ddd dd}: {1}",

DateTime.Today.AddDays(i),

weather[i]);

box.Height = 145;

box.Width = 130;

pic.Dock = DockStyle.Fill;

pic.SizeMode = PictureBoxSizeMode.CenterImage;

box.Controls.Add(pic);

switch (weather[i])

{

case Weather.Sunny:

pic.Image = Resources.sunny;

Page 20: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

break;

case Weather.Cloudy:

pic.Image = Resources.cloudy;

break;

case Weather.Snowy:

pic.Image = Resources.snowy;

break;

case Weather.Rainy:

pic.Image = Resources.rainy;

break;

}

this.forecastPanel.Controls.Add(box);

}

}

9. Implement the ShowForecast function to call the weather service and call the DisplayForecast

function to display the results. To do this, insert the following code shown in bold inside the

ShowForecast function.

(Code Snippet – Web Services And Identity Lab - Ex01 ShowForecast)

C#

private void ShowForecast(int days, int zipCode)

{

using (ServiceClient client = new ServiceClient())

{

Weather[] weather = null;

using (UserCredentialsDialog dialog = new UserCredentialsDialog())

{

dialog.Caption = "Connect to WeatherStation Service";

dialog.Message = "Enter your credentials";

if (dialog.ShowDialog() == DialogResult.OK)

{

if (dialog.SaveChecked)

{

dialog.ConfirmCredentials(true);

}

client.ClientCredentials.UserName.UserName = dialog.User;

client.ClientCredentials.UserName.Password =

dialog.PasswordToString();

try

{

if (days == 3)

{

Page 21: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

weather = client.GetThreeDaysForecast(zipCode);

}

else if (days == 10)

{

weather = client.GetTenDaysForecast(zipCode);

}

this.DisplayForecast(weather);

}

catch (SecurityAccessDeniedException ex)

{

MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

client.Abort();

}

catch (MessageSecurityException)

{

MessageBox.Show("Could not authenticate your

credentials.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

client.Abort();

}

}

}

}

}

10. Save all the changes.

Note: As you can see, the client did not use anything special or different from what you would be

normally doing with a classic WCF service.

Exercise 1: Verification

In order to verify that you have correctly performed all steps in this exercise, proceed as follows:

1. In Solution Explorer, right-click the WeatherStationClient project and select Set as StartUp

Project.

2. Start debugging by pressing F5.

Page 22: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 7

Client application

3. Enter any integer value in the ZIP code textbox.

4. Click the Get 3 days button; when prompted for credentials enter the username "john" and the

password "p@ssw0rd".

Figure 8

Client application showing the forecast for 3 days

5. Now, click the Get 10 days button and enter the same credentials (john/p@ssw0rd).

Page 23: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 9

Access is denied message

Note: You will get an "Access is denied" error message since in our authorization conditions for

GetTenDaysForecast we listed paul but not john among the acceptable values of the

username claim. Windows Identity Foundation is throwing a SecurityAccessDeniedException

when the user is not authorized.

6. Click the Get 10 days button again; when prompted for credentials enter the username "paul"

and the password "p@ssw0rd".

Figure 10

Client application showing the forecast for 10 days

Page 24: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Exercise 1: Summary

In this first exercise, we have explored how to modify a traditional WCF service in order to use Windows

Identity Foundation to authenticate and authorize calls. We have learned about token handlers,

ClaimsAuthorizationManager, hosting options and the basics of driving Windows Identity Foundation’s

behavior via configuration. Now that we are comfortable with the main differences between the object

model used by WCF and the one in Windows Identity Foundation, we can move to consider the more

common cases in which we invoke services by using issued tokens.

Exercise 2: Accepting Tokens from an

Active Directory Federation Services

(ADFS) STS

In this exercise, you will modify the service from the previous exercise for accepting tokens from an

existing Active Directory Federation Services (ADFS) STS. You can expect this to be by far the most

common scenario in which you will take advantage of an STS: Windows Identity Foundation makes this

task very easy, thanks to its integration with Visual Studio and the use of federation metadata.

Note that in a real world scenario this task would require two steps:

Configuring the RP application for accepting tokens from the STS

Configuring the STS for issuing token for the RP application being developed

The current exercise focuses on the first step: the second step is unnecessary in our case. In order to

make the lab more agile, we will take advantage of an instance of Active Directory Federation Services

(ADFS) that is available through the Internet. Such an instance has been pre-provisioned with the data of

the RP being used in this lab; hence, it will start issuing tokens for us as soon as we will request them.

For this reason, it is of key importance that the application URI and the certificates will follow exactly

what is specified in the lab instructions.

Page 25: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 11

Invoking WeatherStationService with a token obtained from federatedidentity.net

Task 1 - Modifying the Service to Accept Tokens Issued by an STS Published via Active Directory

Federation Services (ADFS)

1. Open Microsoft Visual Studio 2010 with administrator privileges. From Start | All Programs |

Microsoft Visual Studio 2010, right-click on Microsoft Visual Studio 2010 and select Run as

administrator.

2. Open the WeatherStation.sln solution file located in the

%YourInstallationFolder%\Labs\WebServicesAndIdentity\Source\Ex2-OnlineSTS\Begin folder.

Note: The starting solution is based on the Exercise 1 solution. It contains a Windows client

application that consumes a simple WCF service which will be modified to use an online STS.

3. On the Solution Explorer, right-click the http://localhost/WeatherStationService project and

select Add STS reference.

4. When the Federation Utility window shows up perform the following tasks for each step in the

wizard.

a. On the Welcome page click Next to continue using the pre-populated fields.

Page 26: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 12

Welcome page

b. Click Next on the list of services to configure.

Page 27: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 13

Services list

c. On the STS options page, select the third option button ("Use an existing STS"), set the

STS metadata location to https://ip-sts-

01.federatedidentity.net/federationmetadata/2007-06/federationmetadata.xml and

click Next.

Page 28: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 14

Selecting a STS option

d. Select Disable certificate chain validation and click Next.

Page 29: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 15

Certificate chain validation

e. Select the Enable encryption option and then select the Select an existing certificate

from store option.

f. Click Select Certificate and select the certificate CN=WeatherStationService.

Page 30: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 16

Using encryption with WeatherStationService certificate

Page 31: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 17

Using encryption with WeatherStationService certificate

g. Click Next.

h. In the Offered Claims page, click Next.

Page 32: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 18

Select claims window

i. On the Summary page, review the changes and click Finish.

Page 33: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 19

Summary

5. Open the Web.config file of the http://localhost/WeatherStationService project.

6. Add the following attribute to the

system.serviceModel/bindings/ws2007FederationHttpBinding/binding/security/message

element.

(Code Snippet – Web Services And Identity Lab - Ex02 Asymmetric Key)

XML

<ws2007FederationHttpBinding>

<binding name="WeatherStationService.IService_ws2007FederationHttpBinding">

<security mode="Message">

<message

issuedKeyType="AsymmetricKey"

>

...

Page 34: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Task 2 - Modifying the Client in Order to Secure Calls to the Service via Issued Token

1. Update the service reference in the WeatherStationClient application. To do this, on the

Solution Explorer, expand the Service References folder in the WeatherStationClient project.

Right-click ServiceReference1 and select Update Service Reference.

2. Open the app.config file from the WeatherStationClient project.

3. Update the issuer in the service binding to use the address for username and password

authentication instead of certificate-based authentication. To do this, replace the issuer

element located inside

system.serviceModel/bindings/customBinding/binding/security/secureConversationBootstra

p/issuedTokenParameters with the following snippet.

(Code Snippet – Web Services And Identity Lab - Ex02 UsernameMixed Issuer)

XML

</additionalRequestParameters>

<issuer address="https://ip-sts-

01.federatedidentity.net/adfs/services/trust/13/usernamemixed"

bindingConfiguration="https://ip-sts-

01.federatedidentity.net/adfs/services/trust/13/usernamemixed"

binding="ws2007HttpBinding">

<identity>

<certificate

encodedValue="MIIGKjCCBRKgAwIBAgIKKwWMagAFAAF3hDANBgkqhkiG9w0BAQUFADCBizETMBEG

CgmSJomT8ixkARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEUMBIGCgmSJomT8ixkAR

kWBGNvcnAxFzAVBgoJkiaJk/IsZAEZFgdyZWRtb25kMSowKAYDVQQDEyFNaWNyb3NvZnQgU2VjdXJl

IFNlcnZlciBBdXRob3JpdHkwHhcNMTAwMzI0MTcwNTI3WhcNMTEwMjE5MTgyNDUzWjB4MQswCQYDVQ

QGEwJVUzELMAkGA1UECBMCd2ExEDAOBgNVBAcTB3JlZG1vbmQxEjAQBgNVBAoTCW1pY3Jvc29mdDEM

MAoGA1UECxMDaWRhMSgwJgYDVQQDEx9pcC1zdHMtMDEuZmVkZXJhdGVkaWRlbnRpdHkubmV0MIGfMA

0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqQB1CIW67PoTYJPc5wgjF9qtyKHToKVesfMPgE5oNtg+d

47DAHllO0vCGvhWmsaJhbimLXK1GzTno/pNMorvFqVQNV9Z9WUxw6tw6VLaUEDBaQ/Afd8SyoljDna

Zuxn6tqLjGBR+QgX+SBFFyiQD9iZwVLc+7cblf9lRGoG9kfQIDAQABo4IDJDCCAyAwCwYDVR0PBAQD

AgSwMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATB4BgkqhkiG9w0BCQ8EazBpMA4GCCqGSI

b3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAwCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBLTALBglghkgB

ZQMEAQIwCwYJYIZIAWUDBAEFMAcGBSsOAwIHMAoGCCqGSIb3DQMHMB0GA1UdDgQWBBTpy6XhrWHQg+

IRMqEPWBPt9nGZCTAfBgNVHSMEGDAWgBQUVcQ54D0u0VUuSJaw2H4UIgaTvDCCAQoGA1UdHwSCAQEw

gf4wgfuggfiggfWGWGh0dHA6Ly9tc2NybC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL01pY3

Jvc29mdCUyMFNlY3VyZSUyMFNlcnZlciUyMEF1dGhvcml0eSg1KS5jcmyGVmh0dHA6Ly9jcmwubWlj

cm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9NaWNyb3NvZnQlMjBTZWN1cmUlMjBTZXJ2ZXIlMjBBdX

Rob3JpdHkoNSkuY3JshkFodHRwOi8vY29ycHBraS9jcmwvTWljcm9zb2Z0JTIwU2VjdXJlJTIwU2Vy

dmVyJTIwQXV0aG9yaXR5KDUpLmNybDCBvwYIKwYBBQUHAQEEgbIwga8wXgYIKwYBBQUHMAKGUmh0dH

A6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvbXNjb3JwL01pY3Jvc29mdCUyMFNlY3VyZSUyMFNlcnZl

ciUyMEF1dGhvcml0eSg1KS5jcnQwTQYIKwYBBQUHMAKGQWh0dHA6Ly9jb3JwcGtpL2FpYS9NaWNyb3

NvZnQlMjBTZWN1cmUlMjBTZXJ2ZXIlMjBBdXRob3JpdHkoNSkuY3J0MD8GCSsGAQQBgjcVBwQyMDAG

KCsGAQQBgjcVCIPPiU2t8gKFoZ8MgvrKfYHh+3SBT4PC7YUIjqnShWMCAWQCAQYwJwYJKwYBBAGCNx

UKBBowGDAKBggrBgEFBQcDAjAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAX3OLpn7dtTwx

UdTbUQQpkmBDVgwOItpIuIykQw8ab7y94weVBkF58DX5KoZ+44eEq9kDh/LKBA5ncTrrNKc8TRypjB

M1JgvaP+7WDStb4ll07r8Ka7Zskb+4RGFnZDVP91zMq6aw7C63UHCMQCMv4K7amKuq+dxJEEp+BCRy

Page 35: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

iMhbt0QQAY2Fv+IrEf/unLvV/TheZ7J5meKLV4tvZaAU4zFzHbfaZ1tGSr6ldhkL92Qqs8WF1nRfPy

q3Jk+616KVZXyluBhDoK6sCGJdCzmP+CWhaOprCbPrM5GAFSig7TUTQymi87SNAM9H1dVaIfSysjc9

BjhnhFm7HsINtj6S1g==" />

</identity>

</issuer>

</issuedTokenParameters>

4. Save all the changes.

Task 3 - Using Claims for Authorizing the Service Call

Note: In exercise 1, we used MyClaimsAuthorizationManager, a class in the Windows Identity

Foundation SDK sample collection, to impose that only calls containing a certain claim type

instance (username in our case) with a certain claim value should be allowed to successfully

take place.

However, claims have much more expressive power and can describe much more than the

classic username, roles and attributes; claims can be used to achieve things that would have

been impossible with traditional approaches. One simple example uses claims to express

attributes that have non-string values, such as dates (date of birth, expiration date, etc),

numbers (spending limit, weight, etc) or even structured data. This data can be processed

using criteria that are more sophisticated than the simple existence check (for example, the

user has claims A with value X, or he does not): one example of such a criteria would be

imposing that all the users of the web service should be older than 21. We already examined

how MyClaimsAuthorizationManager leverages the CheckAccess method for embedding the

existence check logic: here we will go one step further and write our own derivation of the

ClaimsAuthorizationManager, implementing an engine capable of evaluating the age check

described above.

1. Right-click on the App_Code folder from the http://localhost/WeatherStationService project

and select Add New Item.

2. Create a new Class and name it AgeThresholdClaimsAuthorizationManager.cs

3. Replace the content of the new class with the following to check access based on the

DateOfBirth claim from the issued token.

(Code Snippet – Web Services And Identity Lab - Ex02

AgeThresholdClaimsAuthorizationManager)

C#

namespace ClaimsBasedAuthorization

{

Page 36: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Xml;

using Microsoft.IdentityModel.Claims;

public class AgeThresholdClaimsAuthorizationManager :

ClaimsAuthorizationManager

{

private static Dictionary<string, int> _policies = new

Dictionary<string, int>();

public AgeThresholdClaimsAuthorizationManager(object config)

{

XmlNodeList nodes = config as XmlNodeList;

foreach (XmlNode node in nodes)

{

XmlTextReader rdr = new XmlTextReader(new

StringReader(node.OuterXml));

rdr.MoveToContent();

string resource = rdr.GetAttribute("resource");

rdr.Read();

string claimType = rdr.GetAttribute("claimType");

if

(claimType.CompareTo(System.IdentityModel.Claims.ClaimTypes.DateOfBirth) != 0)

{

throw new NotSupportedException("Only birthdate claims are

supported");

}

string minAge = rdr.GetAttribute("minAge");

_policies[resource] = int.Parse(minAge);

}

}

public override bool CheckAccess(AuthorizationContext pec)

{

if (_policies.ContainsKey(pec.Resource.First().Value))

{

int minAge = _policies[pec.Resource.First().Value];

string userBirthdate = pec.Principal.Identities[0].Claims

Page 37: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

.Where(c => c.ClaimType ==

System.IdentityModel.Claims.ClaimTypes.DateOfBirth)

.First().Value;

int userAge =

DateTime.Now.Subtract(DateTime.Parse(userBirthdate)).Days / 365;

if (userAge < minAge)

{

return false;

}

}

return true;

}

}

}

Note: The code above is very simple. The class constructor takes care of reading the

authorization conditions from the web.config. The CheckAccess method retrieves the

dateofbirth claim associated with the incoming user, and simply verifies that the

corresponding age is above the threshold established by minAge. The age condition is not

especially realistic in this scenario; however it should give you a good idea of how to use the

object model.

4. Open the Web.config file of the http://localhost/WeatherStationService project.

5. Add the following settings under the microsoft.identityModel/service section with

name="WeatherStationService.Service" to configure the ClaimsAuthorizationManager module

to validate the age to be greater than 21 using the type

AgeThresholdClaimsAuthorizationManager.

(Code Snippet – Web Services And Identity Lab - Ex02 ClaimsAuthorizationManager

configuration)

XML

<microsoft.identityModel>

<service name="WeatherStationService.Service">

...

<claimsAuthorizationManager

type="ClaimsBasedAuthorization.AgeThresholdClaimsAuthorizationManager">

<policy resource="http://localhost/WeatherStationService/Service.svc"

action="GET">

Page 38: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

<claim

claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth"

minAge="21" />

</policy>

</claimsAuthorizationManager>

</service>

</microsoft.identityModel>

6. Save all the changes.

Exercise 2: Verification

In order to verify that you have correctly performed all steps in the exercise, proceed as follows:

1. On the Solution Explorer, right-click on the WeatherStationClient project and select Set as

StartUp Project.

2. To run the application, press Ctrl+F5.

Figure 20

Client application

3. Enter any integer value in the ZIP code textbox.

4. Click on Get 3 days button, when asked for credentials enter the username "frankm" and the

password "p@ssw0rd".

Page 39: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 21

Client application showing forecast for 3 days

5. Click on Get 3 days button again, when asked for credentials enter the username "adamc" and

the password "p@ssw0rd".

Figure 22

Access is denied message

Note: The date of birth for the user adamc is 02/02/1998, therefore you get an "Access is

denied" error message since the user's age is lower than the min age of 21.

Exercise 2: Summary

This short exercise demonstrates how easy it is to configure an application to accept identities from an

existing STS. For the sake of the exercise the external STS was already configured for sending claims to

our application, however the process of configuring Active Directory Federation Services (ADFS) for

issuing claims for an RP is similarly easy and streamlined.

Page 40: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

We also demonstrated how the use of claims allows the creation of sophisticated authorization criteria,

such as comparisons against thresholds, and how the Windows Identity Foundation object model makes

those criteria really easy to implement.

Exercise 3: Invoking a WCF Service on

the Backend via Delegated Access

In Service Oriented Architectures, the composition and chaining of services are the base mechanisms

that allow the reuse of existing services in order to create higher-level functionality. One recurring

problem of composition has to do with access control: how do you make sure that the permissions

granted to the original caller are honored though the layers of multiple services calling other services?

The practice of relying on trusted subsystems, in which the user is verified just at the first layer and all

the calls to the deeper layers are authenticated against applicative credentials, can be very risky; other

mechanisms, such as Kerberos constrained delegation, have infrastructure requirements that are not

always easy (or possible) to enact. Windows Identity Foundation provides a solution to this problem, by

allowing a service to invoke another service by presenting a delegated token.

From an architectural point of view, Windows Identity Foundation achieves this by leveraging the ActAs

mechanisms defined in the WS-Trust protocol. The service handing the original call from the user

requires a token to an STS using its own application credentials, however it also attaches to the request

the token that the current user sent in order to authenticate with the original service. The STS processes

the request and issue a delegated token, which in turn the original service uses for invoking another web

service acting as the user.

From the practical point of view, this means that the WCF developer needs to follow few extra steps

before calling the backend service he needs. In the following exercise we will demonstrate exactly that,

showing how to augment the solution we built in the former exercises with a delegated call to a backend

service.

Page 41: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 23

The identity of the original caller flows through two layers of services, thanks to the ActAs capabilities of

ActAsSTSEx03

Task 1 - Opening the Solution

1. Open Microsoft Visual Studio 2010 with administrator privileges. From Start | All Programs |

Microsoft Visual Studio 2010, right-click Microsoft Visual Studio 2010 and choose Run as

administrator.

2. Open the WeatherStation.sln solution file located in the

%YourInstallationFolder%\Labs\WebServicesAndIdentity\Source\Ex3-

InvokingViaDelegatedAccess\Begin folder.

3. In Solution Explorer, examine the projects that compose the beginning solution.

Page 42: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 24

Exercise initial solution

◦ http://localhost/ActAsStsEx03: a pre-configured STS capable of issuing delegated

tokens

◦ http://localhost/IdentityProviderStsEx03: a development STS which plays the role of

the identity provider in our scenario; it will issue the tokens that will be used from the

client for calling the first service in the chain, WeatherStationServiceEx03

◦ http://localhost/SatelliteImagesServiceEx03: a service that returns satellite images; it

will not be invoked directly from the client; instead, it will be called with delegated

Page 43: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

credentials by WeatherServiceEx03, which will include the results (if any) in its own

return message to the client

◦ http://localhost/WeatherStationServiceEx03: a service that returns weather forecast

information

◦ WeatherStationClient: a WinForms client application that consumes

WeatherStationServiceEx03

Task 2 - Adding a Reference to the Backend Service

1. In Solution Explorer, right-click the http://localhost/WeatherStationServiceEx03/ project and

select Add Service Reference.

Figure 25

Adding a Service Reference

2. In the Add Service Reference dialog, click Discover. In the Services panel, select

SatelliteImageServiceEx03/Service.svc and click OK.

Page 44: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 26

Selecting the SatelliteImageServiceEx03

Note: Notice that the service reference has been added to the project and the

App_WebReferences folder was created with the ServiceReference1 reference.

3. Open the Web.config file of the http://localhost/WeatherStationServiceEx03/ project.

4. Locate the system.serviceModel/client/endpoint element and replace the machine name with

localhost in the address attribute

(address="http://localhost/SatelliteImagesServiceEx03/Service.svc").

XML

<system.serviceModel>

<client>

<endpoint

address="http://localhost/SatelliteImagesServiceEx03/Service.svc"

binding="customBinding" bindingConfiguration="CustomBinding_IService"

contract="ServiceReference1.IService" name="CustomBinding_IService" />

</client>

...

Page 45: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

</system.serviceModel>

5. Locate the system.serviceModel/bindings/ws2007HttpBinding element and paste the

following binding shown in bold.

(Code Snippet – Web Services And Identity Lab - Ex03 Configure IssuedTokenBinding)

XML

<system.serviceModel>

...

<bindings>

...

<ws2007HttpBinding>

<binding name="UsernameBinding">

<security mode="TransportWithMessageCredential">

<message clientCredentialType="UserName"

establishSecurityContext="false" />

</security>

</binding>

<binding name="IssuedTokenBinding">

<security mode="TransportWithMessageCredential">

<message clientCredentialType="Windows"

establishSecurityContext="false" />

</security>

</binding>

</ws2007HttpBinding>

...

</bindings>

...

</system.serviceModel>

6. Locate the CustomBinding_IService binding element (inside

system.serviceModel/bindings/customBinding) and add the following settings to the issuer

element (security/issuedTokenParameters/issuer) to use the binding from the previous step.

(Code Snippet – Web Services And Identity Lab - Ex03 Configure Endpoint)

XML

<system.serviceModel>

...

<bindings>

...

<customBinding>

<binding name="CustomBinding_IService">

<security ...>

<issuedTokenParameters ...>

...

Page 46: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

<issuer

address="https://localhost/ActAsStsEx03/Issue.svc/windows_over_transport"

binding="ws2007HttpBinding" bindingConfiguration="IssuedTokenBinding"

/>

<issuerMetadata

address="https://localhost/ActAsStsEx03/Issue.svc/windows_over_transport/mex"

/>

...

</issuedTokenParameters>

...

</security>

...

</binding>

...

</customBinding>

...

</bindings>

...

</system.serviceModel>

Task 3 - Calling the Backend Service

1. Open the App_Code/Service.cs file from the http://localhost/WeatherStationServiceEx03/

project.

2. Add the following using statements.

(Code Snippet – Web Services And Identity Lab - Ex03 Service Usings)

C#

using System.Collections.ObjectModel;

using System.IdentityModel.Tokens;

using System.ServiceModel;

using System.ServiceModel.Security;

using System.Threading;

using Microsoft.IdentityModel.Claims;

using Microsoft.IdentityModel.Protocols.WSTrust;

3. Paste the following snippet at the beginning of the GetForecast method to call the

SatelliteImageService.

(Code Snippet – Web Services And Identity Lab - Ex03 Calling The SatelliteImageService)

C#

protected WeatherResult GetForecast(int days, int zipCode)

{

IClaimsPrincipal principal = Thread.CurrentPrincipal as IClaimsPrincipal;

Page 47: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

SecurityToken callerToken = principal.Identities[0].BootstrapToken;

// We expect only one identity, which will contain the bootstrap token.

if (principal != null && principal.Identities.Count == 1)

{

callerToken = principal.Identities[0].BootstrapToken;

}

ChannelFactory<ServiceReference1.IServiceChannel> factory = new

ChannelFactory<ServiceReference1.IServiceChannel>("CustomBinding_IService");

factory.ConfigureChannelFactory();

// Create and setup channel to talk to the backend service

ServiceReference1.IServiceChannel channel;

// Setup the ActAs to point to the caller's token so that we perform a

delegated call to the backend service

// on behalf of the original caller.

channel =

factory.CreateChannelActingAs<ServiceReference1.IServiceChannel>(callerToken);

// Call the backend service and handle the possible exceptions

byte[] image = null;

try

{

image = channel.GetSatelliteImage(zipCode);

}

catch (SecurityAccessDeniedException)

{

channel.Abort();

}

Weather[] forecast = new Weather[days];

Random rand = new Random(zipCode + DateTime.Today.DayOfYear);

...

}

Note: Let us examine the code above. First, you are extracting the so called “bootstrap token”

from the ClaimsPrincipal. This is a token issued by IdentityProviderStsEx03 that the service

received with the call from the client application.

Once you obtained the bootstrap token, you need to inject it in the call to

SatelliteImagesServiceEx03 so that it will be used (along with WeatherStationServiceEx03

application identity credentials) to obtain a token from the ActAs STS, which in turn will be

Page 48: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

used to invoke the desired service. The mechanism provided by Windows Identity Foundation

to implement the above is the CreateChannelActingAs extension method.

4. Open the Web.config file of the http://localhost/WeatherStationServiceEx03 project. Locate

the service element in the microsoft.identityModel section, insert a new attribute named

saveBootstrapTokens and set its value as true.

XML

<microsoft.identityModel>

<service saveBootstrapTokens="true">

<audienceUris>

<add value="https://localhost/WeatherStationServiceEx03/Service.svc"/>

</audienceUris>

5. In the http://localhost/WeatherStationServiceEx03/ project under the App_Coder folder, open

the Service.cs file, and then paste the following snippet at the end of the GetForecast method

to return the image from the service.

(Code Snippet – Web Services And Identity Lab - Ex03 Returning The Satellite Image)

C#

return new WeatherResult

{

Forecast = forecast,

SatelliteImage = image

};

6. Compile the solution.

Exercise 3: Verification

In order to verify that you have correctly performed all the steps in exercise four, proceed as follows:

1. In Solution Explorer, right-click the WeatherStationClient project and select Set as StartUp

Project.

2. Start debugging by pressing F5.

Page 49: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Figure 27

Client application

3. Enter any integer value in the ZIP code textbox.

4. Click the Get 3 days button; when prompted for credentials enter the username "john" and the

password "p@ssw0rd".

Figure 28

John gets the forecast

Note: Since john does not have access to the SatelliteImageService, he is unable to retrieve an

image from the service and the Show Satellite button appears disabled.

Page 50: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

5. Click the Get 10 days button again; when prompted for credentials enter the username "paul"

and the password "p@ssw0rd".

Figure 29

Paul gets the forecast

6. The Show Satellite button is now enabled, which suggests that the call to obtain the extra data

succeeded. Click the Show Satellite button and you will see the image from the

SatelliteImageService.

Figure 30

Satellite image

Page 51: Web Services and Identity for Visual Studio 2010 Developersaz12722.vo.msecnd.net/identitytrainingcourse1-5/labs/webservicesand... · By introducing a unified approach to claims-based

Note: Since paul has access to the SatelliteImageService, he is able to retrieve the satellite

image from the service.

Exercise 3: Summary

Being able to perform web service calls acting as another user is a powerful mechanism. This exercise

demonstrated how to enable a WCF service to do that. We have shown how to retrieve the user token

from the context and how to take advantage of the Windows Identity Foundation object model to use

that token in a subsequent WCF service call in order to act as the caller of the first service.

Summary

By completing this Hands-On Lab you have learned:

how to take advantage of Windows Identity Foundation to authenticate and authorize calls to

WCF services.

how to leverage an Active Directory Federation Services (ADFS) STS available online, used as

identity provider

◦ You have also had a taste of how powerful claims-based authorization can be, by

creating custom authorization criteria

Finally, you have learned how to perform delegated services calls across multi layer

architectures without the need to apply any complex infrastructure requirements

You can expect the activities in exercise 2 and exercise 3 to be the most common tasks you will perform

in normal development practice.

We hope that this lab helped you to learn how to benefit in your services from the powerful identity

capabilities that Windows Identity Foundation offers to WCF developers. This Identity Developer

Training Kit barely covers the basics: if you want to know more, plase refer to the SDK and visit

www.microsoft.com/geneva.