Hands-On Lab<br />Introduction to the Access Control Service<br />Lab version: 1.0.0<br />Last updated:  DATE @ "
M/d/yyyy...
The idea behind the scenario is very simple. The ADFSv2 instance can be a trusted issuer for your ACS Service Namespace, m...
In this exercise you will learn how to modify a client in order to obtain a SAML token from an ADFSv2 instance and use it ...
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Introduction to the .NET Access Control Service
Upcoming SlideShare
Loading in …5
×

Introduction to the .NET Access Control Service

601 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
601
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Introduction to the .NET Access Control Service

  1. 1. Hands-On Lab<br />Introduction to the Access Control Service<br />Lab version: 1.0.0<br />Last updated: DATE @ " M/d/yyyy" 9/29/200811/16/2009<br />Contents<br /> TOC h z " Heading 3,2,pp Topic,1,PP Procedure start,3" Overview PAGEREF _Toc245814168 h 3<br />Exercise 1: Using ACS with Symmetric Keys PAGEREF _Toc245814169 h 13<br />Task 1 - Exploring the Initial Solution PAGEREF _Toc245814170 h 15<br />Task 2 - Sign up for .NET Services and create a service namespace PAGEREF _Toc245814171 h 16<br />Task 3 - Set the service to accept & validate ACS tokens PAGEREF _Toc245814172 h 20<br />Task 4 - Configure the ACS Service Namespace to implement access logic for a specific caller PAGEREF _Toc245814173 h 25<br />Task 5 - Configure the client to use ACS to access the Service PAGEREF _Toc245814174 h 30<br />Exercise 1: Verification PAGEREF _Toc245814175 h 33<br />Exercise 1: Summary PAGEREF _Toc245814176 h 36<br />Exercise 2: Using ACS with SAML Tokens PAGEREF _Toc245814177 h 36<br />Task 1 - Configure the ACS service to accept users from a directory PAGEREF _Toc245814178 h 38<br />Task 2 - Create an “ADFSv2 ready” client PAGEREF _Toc245814179 h 44<br />Exercise 2: Verification PAGEREF _Toc245814180 h 49<br />Exercise 2: Summary PAGEREF _Toc245814181 h 50<br />Summary PAGEREF _Toc245814182 h 50<br />Overview<br />The .NET Services Access Control Service (ACS) is a service designed to secure REST web services. ACS allows a REST web services to integrate with both simple clients and enterprise identity technologies using a single code base.<br />ACS simplifies access control by enabling Web service providers to offload the cost and complexity of integrating with various customer identity technologies. Without having to understand and address each of these technologies, Web services can easily integrate with ACS using a simple provisioning process and REST-based management API. Subsequently, the web service can allow ACS to serve as the point of integration for service consumers.<br />This hands-on lab will show you how to take advantage of ACS to manage access control to your REST web services. <br />The lab will explore how to handle access using symmetric keys as credentials, a common practice when accessing REST APIs. ACS extends the common scenario with claims-based access capabilities while maintaining the simplicity of the REST approach.<br />Furthermore, the lab will demonstrate how you can use ACS for easily bridging the gap that traditionally separate the worlds of enterprise services and REST services. You will learn how you can take advantage of preexisting identity infrastructure, such as Active Directory and ADFSv2, for enabling enterprise users to instantly access REST web services.<br />While the samples will be based on .NET and WCF, you will discover that what you will learn about the use of ACS can be easily generalized to other platforms.<br />Objectives<br />In this Hands-On Lab, you will learn how to:<br />Modify your WCF services to take advantage of ACS for handling access control<br />Create and manage ACS Service Namespaces; work with token policies, issuers, scopes and rules<br />Invoke REST web services secured by ACS<br />Obtain tokens from ACS via SAML token, and use them to invoke REST web services<br />System Requirements<br />You must have the following items to complete this lab:<br />Microsoft® Windows® Vista SP2 (32-bits or 64-bits) , Microsoft® Windows Server 2008 SP2 (32-bit or 64-bit), Microsoft® Windows Server 2008 R2, or Microsoft® Windows® 7 RTM (32-bits or 64-bits)<br />Microsoft® .NET Framework 3.5 SP1<br />Microsoft® Visual Studio 2008<br />Microsoft® Windows Identity Foundation Runtime<br />Microsoft® Windows PowerShell<br />Setup<br />You must perform the following steps to prepare your computer for this lab. <br />Run the command file SetupLab.cmd located at %YourInstallationFolder%LabsIntroToAccessControlServiceSourceSetup as administrator (right-click the SetupLab.cmd file and select Run as administrator). This script will just install some code snippets that will be used across the lab and the localhost certificate used in the second exercise by the local STS.<br />Note: For convenience, much of the code is available as Visual Studio code snippets. This command file launches the Visual Studio installer file that installs the code snippets for the lab and then it installs the required certificates to perform this lab.<br />The following screen is shown first. Click Next to continue.<br />Figure 1<br />Running the Configuration Wizard<br />The following screen shows a summary of the steps the Configuration Wizard will make. Click Next to continue to the prerequisite validation.<br />Figure 2<br />Summary of steps in the Configuration Wizard<br />The Configuration Wizard will now check for missing dependencies. If missing dependencies are found, the wizard will aid you in downloading and installing them. After fixing the dependencies you may click Rescan to attempt to detect the remaining dependencies.<br />Figure 3<br />Configuration Wizard showing missing dependencies<br />Finally, when the Configuration Wizard verified that all the prerequisites are in place, click Next to continue with the lab configuration. The next step is to install the Code Snippets.<br />Figure 4<br />Configuration Wizard showing prerequisites<br />When the Visual Studio Content Installer is shown, choose all items from the list (by default all items are selected) and click Next.<br />Figure 5<br />Code snippets for exercises<br />A dialog window appears warning that the file is not signed; choose Yes to proceed anyway.<br />Figure 6<br />Warning dialog window<br />When prompted for the location of the C# snippets, highlight all snippets, click the check box next to My Code Snippets under the Visual Studio 2008 node, and click Next.<br />Figure 7<br />Installation location for C# code snippets<br />Click Finish to install the code snippets.<br />Figure 8<br />Summary of the content to be installed<br />The installation should proceed and install all snippets.<br />Figure 9<br />Installation completed<br />Click Close to dismiss the confirmation dialog.<br />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 back up copy of it before continue with the lab's certificates installation.<br />You can find more information on how to back up a certificate by Exporting the Certificate with the Private Key on this TechNet link.<br />Once closed the code snippets installer, the setup script will proceed with the certificates installation. If prompted, press Y to continue with the required certificates installation.<br />Figure 10<br />Certificates installation finished<br />When finished press any key to close the setup console.<br />Note: In addition to the setup script inside the %YourInstallationFolder%LabsIntroToAccessControlServiceSourceSetup folder, there is a Cleanup.cmd file you can use to uninstall all the code snippets installed by the SetupLab.cmd script.<br />Exercises<br />The following exercises make up this Hands-On Lab:<br />Using ACS with Symmetric Keys<br />Using ACS with SAML Tokens<br />Note: Each exercise is accompanied by a starting solution. These solutions are missing some code sections that are completed through each exercise and therefore will not work if running them directly.<br />Inside each exercise you will also find an end folder where you find the resulting solution you should obtain after completing the exercises. You can use this solution as a guide if you need additional help working through the exercises.<br />Using the Code Snippets<br />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,<br />Add the following using statements.<br />(Code Snippet – Introduction to ACS Lab - Ex01 Default Usings)<br />C#<br />using System.Linq;<br />using Microsoft.IdentityModel.Claims;<br />To add this code snippet in Visual Studio you simply place the cursor where you'd like the code to be inserted, start typing the snippet name, in this case IntroductionToACSLabEx01DefaultUsings, 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. <br />To insert a code snippet using the mouse rather than the keyboard (i.e. for web.config file and any other XML document), right-click where you want the code snippet to be inserted, select Insert Snippet... then My Code Snippets and then select the relevant snippet.<br />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. <br />Estimated time to complete this lab: 50 minutes <br />Exercise 1: Using ACS with Symmetric Keys<br />Imagine you run a web site that offers weather forecast reports. Your business model has always been selling access to your web pages, but your customers are increasingly pressuring you to provide programmatic access to your forecasts, so that they can be easily integrated in their applications.<br />You want to satisfy their demands, but you don’t want to get caught in managing multiple relationships or invest too much energy in handling access control for your API.<br />Enter the Access Control Service (ACS). You can outsource to ACS most of your access control logic.<br /> ACS takes care of authenticating your customers for you, issuing them a token that proves they successfully authenticated and that contains information about their access rights. All you need to do from your application is verifying the presence of such a token in the call, and enforce the access control policies that its content entails.<br />The interaction described above is commonly known as claims-based access, from the fact that the user attributes included in the token are known as claims. A claim is a statement about a user, issued by an authority: if an application receives claims about a user from an authority it trusts, it will assume those claims to be true and act upon them accordingly. This is a very natural process, which we commonly experience in real life without even knowing it: every time you show your driver’s license for proving your age you are using claims.<br />Claims-based access is common practice for enterprise grade SSO solutions, based on open protocols such as WS-Federation, SAML and WS-Trust, however it was not available for REST scenarios until now.<br />ACS implements a new REST-friendly protocol, called WRAP (Web Resource Authorization Protocol), which allows you to request tokens from ACS and use them when invoking REST services. The tokens you obtain from the ACS are Simple Web Tokens, or SWT: their compact format makes them ideal for REST. <br />This exercise will expand on the weather reporting scenario above, and will walk you through the process of: <br />Modifying a WCF service to take advantage of ACS for handling access control<br />Create and manage an ACS Service Namespace; learn how to work with ACS resources (token policies, issuers, scopes and rules)<br />Enable a client to obtain a token from ACS via symmetric key, and use it for invoking the WCF service above in a RESTful way<br />Figure 11<br />A summary of the scenario enabled by this exercise. The client requests (1) and obtains (2) a SWT token from the Access Control Service. The client then uses the SWT to invoke the service (3) and, upon successful authorization in ACSAuthorizationManager (4), reaches the intended service method.<br />Task 1 - Exploring the Initial Solution<br />The exercise will modify an existing solution, which already contains a WCF service and its client ready for you to try. The service is exposed with a REST-friendly binding, and has no authentication. Let’s take a look at it. Open Microsoft Visual Studio 2008 with administrator privileges. From Start | All Programs | Microsoft Visual Studio 2008, right-click on Microsoft Visual Studio 2008 and select Run as administrator.<br />Open the SimmetricKey.sln solution file located in the %YourInstallationFolder%LabsIntroToAccessControlServiceSourceEx01-UsingACSWithSymmetricKeyBegin folder.<br />Right click on the Service project (in Solution Explorer), and select Debug | Start new instance to run the Service. The web service is a façade to the weather reporting system, and offers two methods corresponding to two different reports for a given zip code: one that spawns three days and another that covers ten days.<br />Figure 12<br />Weather Service running in console<br />Right click on the Client project (in Solution Explorer), and select Debug | Start new instance to run the Client. The client will request the three days report and the ten days one after the other. We have no authentication or authorization mechanism in place, hence both calls will succeed.<br />Figure 13<br />Weather Service Client running<br />Close both applications. Both applications may be closed by pressing Enter on their window.<br />Task 2 - Sign up for .NET Services and create a service namespace<br />In this task, you will create a new .NET Services project. <br />Navigate to https://netservices.azure.com. You will be prompted for your Windows Live ID credentials if you are not already signed in.<br />Create a new Project. Type a project name, such as your company name or your name, accept the Terms of Use and click the OK button. <br />Figure 14<br />Azure .Net Services – Create a new project<br />Now you will add the first Service Namespace to the project just created. A Service Namespace represents a namespace for the Service Bus and the Access Control Service. To do this, click on the name of the newly created Project and then click the Add Service Namespace link.<br />Figure 15<br />Azure .Net Services – Project Summary<br />Type in a name for your Service Namespace, select a Region for your service to run in, and click the Create button. Make sure to validate the availability of the name first. Service names must be globally unique as they are in the cloud and accessible by whomever you decide to grant access.<br />Please be patient while your service is activated. It can take a few minutes while it is provisioned. <br />You may have to refresh the browser to show the service is active. <br />Figure 16<br />Azure .Net Services – Creating a Service Namespace<br />Figure 17<br />Azure .Net Services – Project Summary listing the Service Namespaces<br />Click on the Service Namespace just created and review the information like the management key, the different endpoints to interact with the Access Control Service, etc.<br />Figure 18<br />The Service Namespace details<br />Note: To sign in at any time, simply navigate to https://netservices.azure.com, click Sign In and provide your Live ID credentials. Clicking the .Net Services tab on the left will list the Services Projects associated with your account.<br />Task 3 - Set the service to accept & validate ACS tokens<br />Your service will need few modifications in order to take advantage of ACS. In summary, you will need to ensure that before your code is invoked the content of the request is inspected, searching for a SWT token. Once verified its presence, you will have to check that it is signed with the correct key (more on this below) and that it contains the claims that your access control policy mandates. <br />WCF provides various extensibility points you can leverage in order to inspect the request before it reaches your service code. In this case, an appropriate way of implementing the checks described above is to derive from the ServiceAuthorizationManager class and embed the necessary logic in it.<br />Once we have our custom ServiceAuthorizationManager class we can insert it in the WCF pipeline, so that it will be automatically executed for us at every service invocation. <br />For the purposes of this lab we are providing a ServiceAuthorizationManager implementation for you, ready to be imported in the WCF service project. In Solution Explorer, right click on the Service project and select Add | Existing Item. Browse to the %YourInstallationFolder%LabsIntroToAccessControlServiceEx01-UsingACSWithSymmetricKeyAssets folder and select ACSAuthorizationManager.cs. Click OK to close the window.<br />Let’s take a quick peek at the ACSAuthorizationManager class. Double-click on the ACSAuthorizationManager.cs file you just imported. The class has just two members and a simple constructor:<br />C#<br />public class ACSAuthorizationManager : ServiceAuthorizationManager<br />{<br /> private TokenValidator validator;<br /> private string requiredClaimType;<br /> public ACSAuthorizationManager(string trustedSolution, string trustedAudienceValue, string trustedSigningKey, string requiredClaimType)<br /> {<br /> this.validator = new TokenValidator(trustedSolution, trustedAudienceValue, trustedSigningKey);<br /> this.requiredClaimType = requiredClaimType;<br /> }<br />Note: The TokenValidator class contains the logic that establishes if the incoming token is well formed and has not been tampered with; the requiredClaimType member represents the claim we expect to receive, and on which we want to perform our access control checks.<br />The constructor simply instantiates a new TokenValidator (more on its initialization parameters below) and assigns the requiredClaimtype member.<br />The key method of a ServiceAuthorizationManager is CheckAccessCore. Let’s examine our override:<br />C#<br />protected override bool CheckAccessCore(OperationContext operationContext)<br />{<br /> // get the authorization header<br /> string authorizationHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Authorization];<br /> if (!string.IsNullOrEmpty(authorizationHeader))<br /> {<br /> // check that it starts with 'simpleapiauth'<br /> if (authorizationHeader.StartsWith(" WRAPv0.8" , StringComparison.OrdinalIgnoreCase))<br /> {<br /> // check there is a ' ' between 'simpleapiauth' and the token<br /> // no other spaces allowed<br /> string[] tokenValues = authorizationHeader.Split(' ');<br /> if (tokenValues.Length == 2)<br /> {<br /> // validate the token<br /> if (this.validator.Validate(tokenValues[1]))<br /> {<br /> // check for an action claim and get the value<br /> Dictionary<string, string> claims = this.validator.GetNameValues(tokenValues[1]);<br /> // use the operation name to determine the required action value<br /> string requiredActionClaimValue = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RelativePathSegments.First();<br /> string actionClaimValue;<br /> if (claims.TryGetValue(this.requiredClaimType, out actionClaimValue))<br /> {<br /> // check for " ," delimited values<br /> string[] actionClaimValues = actionClaimValue.Split(',');<br /> // check for the correct action claim value<br /> if (actionClaimValues.Contains(requiredActionClaimValue, StringComparer.OrdinalIgnoreCase))<br /> {<br /> return true;<br /> }<br /> }<br /> }<br /> }<br /> }<br /> }<br /> WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized;<br /> WebOperationContext.Current.OutgoingRequest.Headers.Add(" WWW-Authenticate" , " WRAP" );<br /> return false;<br /> } <br />}<br />Without going too much into details, the method:<br />Inspects the Authorization HTTP header and verifies it is complying with the WRAP protocol<br />Retrieves the token from the header and validates it (more on this later)<br />If the token resulted valid, it retrieves the action corresponding to the method currently being called. It then queries the token to retrieve the values of the claim type indicated by requiredClaimType. If among those values there is the action of the current method, the call is authorized and CheckAccessCore returns True<br />If any of the checks above fail, the method prepares the response to return a 401:Unauthorized code to the caller and exits by returning False<br />As we have seen above, ACSAuthorizationManager relies on the helper class TokenValidator for checking the validity of the incoming token. Also in this case we are providing an implementation for you. In Solution Explorer, right click on the Service project and select Add | Existing Item. Browse to the %YourInstallationFolder%LabsIntroToAccessControlServiceSourceEx01-UsingACSWithSymmetricKeyAssets folder and select TokenValidator.cs. Click OK to close the window.<br />Open TokenValidator.cs by double-clicking on it in Visual Studio. The class TokenValidator contains boilerplate code for performing verifications on the incoming token: let’s take a look at its main parts.<br />The constructor is truly straightforward:<br />C#<br />public TokenValidator(string trustedSolution, string trustedAudienceValue, string trustedSigningKey)<br />{<br /> this.trustedSigningKey = trustedSigningKey;<br /> this.trustedTokenIssuer = string.Format(acsBaseAddress, trustedSolution);<br /> this.trustedAudienceValue = trustedAudienceValue;<br />}<br />Let’s examine the meaning of the parameters it requires:<br />trustedSolution represents the name of your ACS Service Namespace. We will see its meaning in a later task, for now just consider it as a container for the authorization logic stored in ACS, and a part of the address to which you will send requests for tokens.<br />trustedSigningKey represents the key you expect the incoming token to be signed with. It is associated to the authority you trust, in this case an ACS service endpoint.<br />trustedAudienceValue is the intended destination of the call, the address to which we expect the token to be issued for. An unexpected value in this parameter would indicate that the token may have been hijacked from another call<br />The core method of TokenValidator is Validate:<br />C#<br />public bool Validate(string token)<br />{<br /> return this.IsHMACValid(token, Convert.FromBase64String(this.trustedSigningKey))<br /> && !this.IsExpired(token)<br /> && this.IsIssuerTrusted(token)<br /> && this.IsAudienceTrusted(token);<br />}<br />The method uses various utility functions for verifying various characteristics of the token. Is the signature valid? Is the token past its expiration? Is it addressed to its intended audience? And so on.<br />If you want to understand more of the SWT token format, you can examine the implementation of those utility functions: you will discover that the format is extremely simple, and so is the code required to process it.<br />Our service project now contains all the helper code we need for using ACS. Let's modify the service initialization code to include the ACSAuthorizationManager class as appropriate. First, we'll need to add a few parameters that we will have to pass down to ACSAuthorizationManager at initialization time. In Solution Explorer, Service project, double click on the Program.cs file, and add the following code right after the Program class declaration. We described the meaning of all those parameters in the former steps. The Service Namespace and TokenPolicyKey values will be obtained from our ACS settings, and we will fill them in after we will have configured our service namespace in the next task. <br />(Code Snippet – Introduction to ACS Lab - Ex01 Service Constants)<br />C#<br />public class Program<br />{<br />private const string ServiceNamespace = " {insert service namespace here}" ;<br />private const string TokenPolicyKey = " {insert token policy key here}" ;<br />private const string Audience = " http://localhost/weatherforecast" ;<br />private const string RequiredClaimType = " action" ;<br />private const string AcsHostName = " accesscontrol.windows.net" ;<br />public static void Main(string[] args)<br />Update the ServiceNamespace value with the Service Namespace you chose in task 2, step 4. <br />C#<br />private const string ServiceNamespace = " {insert service namespace here}" ;<br />Finally, we will modify the service host to use ACSAuthorizationManager. To do that, in Program.cs add the following code right before the host.Open() invocation: <br />(Code Snippet – Introduction to ACS Lab - Ex01 ACS Instantiation)<br />C#<br />host.AddServiceEndpoint(typeof(IWeatherForecast), binding, new Uri(" http://localhost/weatherforecast" ));<br />host.Authorization.ServiceAuthorizationManager = new ACSAuthorizationManager(<br /> ServiceNamespace,<br /> Audience,<br /> TokenPolicyKey,<br /> RequiredClaimType);<br />host.Open()<br />That’s it. Our service code is now ready to handle requests secured via ACS: we no longer need to worry about handling relationships, credentials or access policies from within our service.<br />All that’s left for us is telling ACS who should have access to our service, and in what terms. In order to do that, we will use the ACS Management Service to modify our Service Namespace according to our needs.<br />Task 4 - Configure the ACS Service Namespace to implement access logic for a specific caller<br />The way in which you configure your ACS Service Namespace is via the ACS management service. You can use the management service for creating, modifying and deleting the resources that are necessary for driving the token issuing behavior you want to obtain. The management service is REST-based and accepts calls secured via your service namespace managed key, which we have obtained in task 2. <br />The November CTP of ACS provides a command line utility, ACM.exe, which allows you to interact with the management service directly from the command prompt.<br />In this task we will use ACM.exe for setting up our Service Namespace so that it will grant one customer selective access to our weatherreport service. Namely, we will grant to our partner access to the Get3DaysForecast method but we will block calls to any other method. As we go through the steps, we will explain the purpose of the resources we will be creating and the role they play in implementing our access control logic.<br />At the end of the task our ACS Service Namespace will be ready to issue tokens expressing our authorization logic, and we will have generated the symmetric key that our customer will use for obtaining tokens from ACS and invoke our service.<br />Before everything else, we need to configure ACM.exe to refer to our Service Namespace and use our management key: this will ensure that all the commands we will enter will manipulate resources within our namespace and that the calls are authenticated with our management credentials. Without this step, we’d have to specify service name and management key for every command. Locate Acm.exe.config in the %YourInstallationFolder%LabsIntroToAccessControlServiceSourceAssets folder and open it in Visual Studio.<br />Change the value of the “service” entry to the name of your Service Namespace. Change the value of the entry “mgmtKey” to the value of the management key for your Service (you can find it on the .NET services portal as shown in task 2, step 5)<br />XML<br /><?xml version=" 1.0" encoding=" utf-8" ?><br /><configuration><br /> <appSettings><br /> <add key=" service" value=" {insert service name here}" /><br /> <add key=" mgmtKey" value=" {insert management key here}" /><br /> <add key=" host" value=" accesscontrol.windows.net" /><br /> </appSettings><br /></configuration><br />We are now ready to manage our solution. We have command line templates ready for you to use for every resource you will need to create: all you need to do is copy & paste them from the text file we provide to a Powershell console and fill in the required parameters. You can find the list of commands in %YourInstallationFolder%LabsIntroToAccessControlServiceSourceEx01-UsingACSWithSymmetricKeyBeginSetup.ps.txt. The first resource we need to create is a Token Policy. To do this, open a Powershell console, navigate to the %YourInstallationFolder%LabsIntroToAccessControlServiceSourceAssets folder and paste the [CREATE_TOKENPOLICY] command from Setup.ps.txt.<br />Powershell<br />$tokenpolicyid = .acm.exe create tokenpolicy -name:weatherforecast -autogeneratekey -simpleout<br />Note: A token policy represents a set of parameters that ACS will use for issuing a token. A service namespace can contain multiple token policies.<br />A token policy is defined by four properties:<br />Id: unique identifier which characterizes the resource. Every ACS resource has one: it can be used for constructing the resource URI. The Id is assigned by the service at creation time, hence we don’t need to specify it.<br />DisplayName: a mnemonic moniker assigned to the resource. As for Id, ever ACS resource has one: however it does not have to be unique. The ACM tool represents DisplayName with the parameter name.<br />DefaultTokenLifetimeInSeconds: The number of seconds that the token will be valid for. The ACM tool represents this parameter as timeout: if you don’t specify it, as shown in our command line, the default value of 28800 seconds (8 hours) will be used.<br />SigningKey: The signing key ACS uses to sign tokens issued with this token policy. ACS sign tokens via HMACSHA256 algorithm, using 32 byte keys. ACM gives you the choice of either specify a key value, via –key parameter, or rely on the service to generate one via –autogenerate parameter. <br />Next, we need to create an ACS Scope that will gather all our access control logic that will have to be triggered when a request is sent to the URI of our weather forecast REST service. To do this, copy and paste the command [CREATE_SCOPE] from Setup.ps.txt.<br />Powershell<br />$scopeid = .acm.exe create scope -name:weatherforecast -appliesto:http://localhost/weatherforecast -tokenpolicyid:$tokenpolicyid -simpleout<br />Note: A scope is, as mentioned, the mechanism that ACS uses for associating settings to a given resource URI. As for the token policies, a service namespace can include multiple scopes. Besides the Id and DisplayName properties, common to every ACS resource, a scope is defined by:<br />AppliesTo: The URI of the resource for which we want to specify access control logic. ACM represents this with the –appliesto parameter.<br />TokenPolicyId: The tokens issued for accessing the resource specified in AppliesTo will follow the setting specified by the token policy represented by TokenPolicyId. ACS represents this value with the parameter –tokenpolicyid.<br />The time has come to define the intended audience of our service: we need to tell ACS how to recognize if a call comes from a legitimate source. To do this, copy and paste the command [CREATE_ISSUER] from Setup.ps.txt.<br />Powershell<br />$issuerid = .acm.exe create issuer -name:weatherforecastclient -issuername:weatherforecastclient -autogeneratekey -simpleout<br />Note: An issuer in ACS describes the cryptographic material that a caller will use when requesting a token. It will be used for authenticating the call and deciding which authorization logic should be applied for the specific service consumer.<br />The defining properties of an issuer in ACS are:<br />IssuerName: The name that the issuer will use for identifying itself in the token request. Note that this is different from the Name property, which is just a friendly name and never leaves the boundaries of the management service. ACM uses –issuername for representing this parameter.<br />Algorithm: This parameters determine which kind of signature ACS should expect for tokens coming from this issuer. The possible values are Symmetrick256Key, the default, and X509. We will discuss the X509 option more in depth in the next exercise.<br />CurrentKey: The key that ACS will need to use for verifying the signature of tokens coming from this issuer. If the algorithm is Symmetric256Key this will be a 32-byte SHA-256 key. If algorithm is X509, this will be a base64 encoded certificate. ACM represents this parameter with –key.<br />In our specific example we are using the option –autogeneratekey, which sets the algorithm to Symmetric256Key , creates a new 32-byte key and assigns it to this issuer. This will be the key that we will have to distribute to our intended service consumer, so that it will be able to use it for requesting tokens.<br />We finally have all the settings in place for describing our desired access control logic. In this exercise we will do something extremely simple, we will grant the right to call our Get3DaysForecast method to the issuer we previously defined and we will exclude everybody else. In practice, this means creating an ACS Rule that allows access to the Get3DaysForecast operation for any client associated to the issuer key previously created. To do this, copy and paste the command [CREATE_RULE] from Setup.ps.txt.<br />Powershell<br />.acm.exe create rule -scopeid:$scopeid -inclaimissuerid:$issuerid -inclaimtype:Issuer -inclaimvalue:weatherforecastclient -outclaimtype:action -outclaimvalue:Get3DaysForecast -name:client3days<br />Note: A rule describes the logic that should be executed when a request from a certain issuer to obtain a token for a certain resource is received. Given an incoming claim type and value, it specifies which claim type and value should be included in the token the ACS will issue (according to a given token policy). The value of the outgoing claim will contain an indication if the service should allow access to the resource being requested (if access is denied, there won't be an outgoing claim). The main parameters you need to specify when creating a rule are:<br />-scopeid: The identifier of the scope in which the rule is supposed to be triggered. The rule will be examined whenever a request to the AppliesTo resource of the indicated scope is received<br />-inclaimissuerid: The identifier of the issuer of the token we are examining. This must be a valid (existing) issuer ID.<br />-inclaimtype: The type of the claim in the token we received in the request to ACS for which we want to specify an access control condition<br />-inclaimvalue: Indicates which value of the claim type indicated in inclaimtype should elicit the execution of the rule<br />-outclaimtype: The type of the claim that should be issued by ACS in case all the input conditions are a match with the incoming token.<br />-outclaimvalue: The value of the claim that should be issued by ACS in case all the input conditions are a match with the incoming token.<br />-passthrough: If specified, ACS simply rewrites the input claim type & value in the token it will issue to the requestor.<br />ACS is now ready to handle requests for our service: we just need to make sure that our service will recognize tokens issued according to the token policy we just defined. To do this, first get the token policy key from ACS using the following command. Once the command finished to execute, select the key from the console and perform a right-click (this will put the highlighted text in the clipboard). Don't close the Powershell window, as we will be using it again in the verification part. To get the key, copy and paste the command [GET_TOKENPOLICY_KEY] from Setup.ps.txt.<br />Powershell<br />.acm.exe get tokenpolicy -id:$tokenpolicyid<br />Figure 19<br />Get the token policy key generated by ACS<br />Paste the token policy key you just copied in the clipboard into the TokenPolicyKey constant on ServiceProgram.cs file.<br />C#<br />private const string TokenPolicyKey = " {insert token policy key here}" ;<br />We are all set for starting to receive calls. All we need is provisioning our customer with the issuer key we generated in step 5; that value and few lines of code for handling ACS token requests is all our customer needs for gaining access to our service.<br />Task 5 - Configure the client to use ACS to access the Service<br />Let’s modify our initial client with the code that is necessary for requesting a token from ACS and using the resulting token for securing the call to the service.<br />In Solution Explorer, Client project, double click on the Program.cs file. Add the following using directives at the beginning of the file for the code we'll be adding later. <br />(Code Snippet – Introduction to ACS Lab - Ex01 Client Usings)<br />C#<br />namespace Client<br />{<br /> using System;<br /> using System.Collections.Specialized;<br /> using System.Linq;<br /> using System.Net;<br /> using System.ServiceModel;<br /> using System.ServiceModel.Security;<br /> using System.ServiceModel.Web;<br /> using System.Text;<br /> using System.Web;<br /> public class Program<br />In Program.cs, insert the following code right after the Program class declaration. . We'll update the Service Name and Issuer Key in the next task. <br />(Code Snippet – Introduction to ACS Lab - Ex01 Client Parameters)<br />C#<br />public class Program<br />{<br /> private const string ServiceNamespace = " {insert service namespace here}" ;<br /> private const string IssuerName = " weatherforecastclient" ;<br /> private const string IssuerKey = " {insert issuer key here}" ;<br /> private const string AcsHostName = " accesscontrol.windows.net" ;<br /> public static void Main(string[] args)<br /> {<br />Change the client to use the issuer key generated in the previous task. To do this, first get the issuer key from ACS using the following command. Once the command generates its output, select the key from the console and do a right click (this will put the highlighted text in the clipboard). To get the issuer key, copy and paste the command [GET_ISSUER_KEY] from Setup.ps.txt.<br />Powershell<br />.acm.exe get issuer -id:$issuerid<br />Figure 20<br />Get the issuer key generated by ACS<br />Copy the issuer key from the Powershell console and paste it into the IssuerKey constant on Client Program.cs file.<br />C#<br />private const string IssuerKey = " {insert issuer key here}" ;<br />Update the service name (the one you’ve got in Task 2, step 4) used in the client ClientProgram.cs file. To do this, replace the ServiceNamespace constant in the code. <br />C#<br />private const string ServiceNamespace = " {insert service namespace here}" ;<br />The first thing we need to do in our code is requesting a token from ACS. Add the following code at the end of Program class. <br />(Code Snippet – Introduction to ACS Lab - Ex01 GetACSToken Method)<br />C#<br />...<br /> private static string GetACSToken()<br /> {<br /> // request a token from ACS<br /> WebClient client = new WebClient();<br /> client.BaseAddress = string.Format(" https://{0}.{1}" , ServiceNamespace, AcsHostName);<br /> NameValueCollection values = new NameValueCollection();<br /> values.Add(" wrap_name" , IssuerName);<br /> values.Add(" wrap_password" , IssuerKey);<br /> values.Add(" applies_to" , " http://localhost/weatherforecast" );<br /> byte[] responseBytes = client.UploadValues(" WRAPv0.8" , " POST" , values);<br /> string response = Encoding.UTF8.GetString(responseBytes);<br /> return response<br /> .Split('&')<br /> .Single(value => value.StartsWith(" wrap_token=" , StringComparison.OrdinalIgnoreCase))<br /> .Split('=')[1];<br /> }<br /> }<br />}<br />Note: Requesting a token from ACS via WRAP protocol and SWT token format is extremely simple: we just POST a name/value collection to our service namespace, containing the URI of the service we want to invoke and the issuer credentials we configured. <br />At the beginning of the Main method add code to retrieve an ACS token using the GetACSToken method we just added. Insert the following code at the beginning of Main():<br />(Code Snippet – Introduction to ACS Lab - Ex01 GetACSToken invocation)<br />C#<br />public static void Main(string[] args)<br />{<br /> string acsToken = GetACSToken();<br />...<br />To invoke the service using the token we received from ACS it's necessary to add it in the " authorization" HTTP header (there are other ways of doing it, which we won’t explore here: please refer to the online documentation of ACS). To do that, insert the following code right after the OperationContextScope:<br />(Code Snippet – Introduction to ACS Lab - Ex01 Client authorization header)<br />C#<br />using (new OperationContextScope(proxy as IContextChannel))<br />{<br /> string authHeaderValue = " WRAPv0.8" + " " + HttpUtility.UrlDecode(acsToken);<br /> WebOperationContext.Current.OutgoingRequest.Headers.Add(" authorization" , authHeaderValue);<br /> // call the service and get a response<br />This concludes the steps that a client needs to perform in order to be able to invoke REST services protected by ACS. In the next task we will verify how our new service works.<br />Exercise 1: Verification<br />In order to verify that you have correctly performed all steps in exercise one, proceed as follows:<br />Right click on the Service project (in Solution Explorer), and select Debug | Start new instance to run the Service.<br />Figure 21<br />Service console<br />Right click on the Client project (in Solution Explorer), and select Debug | Start new instance to run the Client.<br />Figure 22<br />Client console showing the 3 days forecast but not the 10 days forecast because the user don’t have access to that.<br />Verify that the 3 days forecast is retrieved by looking at the console output. You'll also notice that the console displays an error on the following line. This is exactly in line with expectations: our rule granted this client access only to the Get3DaysForecast method, hence the attempt to access Get10DaysForecast was blocked with a (401) Unauthorized return code.<br />Let’s see how easy it is to manage access control now that ACS takes care of it. We will add an ACS Rule that allows access to the Get10DaysForecast operation. To do this, copy and paste the command [CREATE_RULE_10DAYS] from Setup.ps.txt<br />Powershell<br />.acm.exe create rule -scopeid:$scopeid -inclaimissuerid:$issuerid -inclaimtype:Issuer -inclaimvalue:weatherforecastclient -outclaimtype:action -outclaimvalue:Get10DaysForecast -name:client10days<br />Figure 23<br />Creating an ACS rule in PowerShell<br />Now that the new rule is in place, the client should be able to access both forecasts. Right click on the Client project (in Solution Explorer), and select Debug | Start new instance to run the Client.<br />Figure 24<br />Client console showing both forecasts<br />Exercise 1: Summary<br />In this exercise you learned how to modify your existing WCF REST services to rely on ACS for authentication and authorization, and walked through the changes that enable client applications to invoke services protected by ACS.<br />You have been introduced to the main ACS resources and their basic properties, and you have learned how to work with them for implementing simple access control logic. <br />Finally, you experienced first-hand how easy it is to change access control settings for your REST services without having to touch the code of the service itself.<br />This exercise barely scratched the surface of what can be achieved with ACS and claims-based access: in the next exercise we will go a bit deeper and demonstrate slightly more sophisticated rules.<br />Exercise 2: Using ACS with SAML Tokens<br />In the first exercise we have shown how you can use ACS for enabling claims-based access without requiring anything more than the classic tools you’d use in REST API integration scenarios. In this exercise we will explore a more advanced case.<br /><ul><li>Let’s say you want to make your REST service available to the users stored in a business repository such as Active Directory: this is a common requirement, but one that traditional approaches to REST security fail to address. ACS solves this situation: if that repository has an ADFSv2 instance associated to it, ACS can easily leverage it for enabling AD accounts to securely invoke REST services.
  2. 2. The idea behind the scenario is very simple. The ADFSv2 instance can be a trusted issuer for your ACS Service Namespace, much like the issuer we defined in task 4 of the former exercise: the only difference is that it will issue tokens in SAML format instead of SWT. A client will request ACS tokens by sending one of such SAML tokens: the claim content of the SAML token is what the ACS will use for determining the content of the token it will issue to the requestor. From now on, it will be business as usual: the service will receive an SWT token, precisely as in shown in the first exercise, and will use it for determining access.
  3. 3. In this exercise you will learn how to modify a client in order to obtain a SAML token from an ADFSv2 instance and use it for requesting a token from ACS. You will also see how you can leverage the ADFSv2 metadata documents for automating part of the settings that the management service needs for configuring access. Finally, you will see how claims allow you to leverage user attributes such as group memberships for creating sophisticated access logic to your REST web service.</li></ul>Figure 25<br />A summary of the scenario enabled by this exercise. The client requests (1) and obtains (2) a SAML token from the ADFSv2 instance; it uses the same SAML token for requesting a token from ACS (3) and obtains a SWT token in return (4). The client then uses the SWT to invoke the service (5) and, upon successful authorization in ACSAuthorizationManager (6), reaches the intended service method.<br />Task 1 - Configure the ACS service to accept users from a directory<br />In this task we are going to build up on the ACS service we have built in exercise 1.<br />We already have a service namespace and a token policy that our service is configured to trust: what we need to do is define a new issuer, which will represent the ADFSv2 authority, and create the appropriate rules that will process the incoming SAML token and produce access decisions. <br />The exercise will modify an existing solution, which already contains a WCF service and its client ready for you to try. Open Microsoft Visual Studio 2008 with administrator privileges. From Start | All Programs | Microsoft Visual Studio 2008, right-click on Microsoft Visual Studio 2008 and select Run as administrator. <br />Open the ACSWithSAML.sln solution file located in the %YourInstallationFolder%LabsIntroAccessControlServiceSourceEx02-UsingACSWithSAMLTokensBegin folder.<br />In Solution Explorer, Service project, double click on the Program.cs file. Update the ServiceNamespace value with the service namespace you chose in the first exercise, task 2, step 4. <br />C#<br />private const string ServiceNamespace = " {insert service namespace here}" ;<br />We'll now need to update our service to recognize tokens issued according to the token policy we defined on the first exercise. To do this, first get the token policy key from ACS using the following command in a Powershell console (navigate to %YourInstallationFolder%LabsIntroAccessControlServiceSourceAssets). Once the command finishes execution, select the key from the console and perform a right-click (this will put the highlighted text in the clipboard). <br />Powershell<br />.acm.exe getall tokenpolicy<br />Figure 26<br />Get the token policy key generated by ACS<br />Paste the token policy key you just copied in the clipboard into the TokenPolicyKey constant on ServiceProgram.cs file.<br />C#<br />private const string TokenPolicyKey = " {insert token policy key here}" ;<br />Run the local STS that will simulate an ADFSv2. To do this, open a command prompt as administrator on %YourInstallationFolder%LabsIntroToAccessControlServiceSourceEx02-UsingACSWithSAMLTokensAssets and type LocalSTS.exe and keep it open for the rest of the exercise.<br />Figure 27<br />Running LocalSTS tool<br />Note: ADFSv2 is a server product with specific infrastructure requirements, among which there is Active Directory. Rather than forcing you to download, configure and manage a large virtual machine file, in this hands-on lab we will simulate an ADFSv2 instance with a custom STS written using Windows Identity Foundation. From the developer perspective the experience is absolutely equivalent: the instructions we give here would apply without any modification if the STS would be exposed by an ADFSv2 instance.<br />Now you will configure our STS as a trusted issuer on ACS. ACS is able to automate a large part of the operation, simply by taking advantage of the metadata exposed by the STS itself. In this lab we provide a tool, FedMetadataClient, which will help you to send to the management service the opportune settings. Similarly to what you have done for the ACM tool in exercise 1, you need to configure the FedMetadataClient tool by opening the FedMetadataClient.exe.config file (from LabsIntroToAccessControlServiceSourceEx02-UsingACSWithSAMLTokensAssets) and assigning the right values to the management key and service name. You got those two values on Task 2 of the first exercise, on step 4 (when you chose the Service Namespace).<br />XML<br /><?xml version=" 1.0" encoding=" utf-8" ?><br /><configuration><br /> <appSettings><br /> <add key=" stsBaseAddress" value=" localhost/localsts" /><br /> <add key=" stspath" value=" Trust/13/UserName" /><br /> <add key=" serviceNamespace" value=" {insert service namespace here}" /><br /> <add key=" acsHostName" value=" accesscontrol.windows.net" /><br /> <add key=" applies_to" value=" http://localhost/weatherforecast" /><br /> <add key=" mgmtKey" value=" {insert management key here}" /><br /> </appSettings><br /></configuration><br />Run the FedMetadataClient.exe tool. To do this, open command prompt on %YourInstallationFolder%LabsIntroToAccessControlServiceSourceEx02-UsingACSWithSAMLTokensAssets and type FedMetadataClient.exe<br />Figure 28<br />Running FedMetadataClient from command line<br />The FedMetadataClient tool retrieves all the relevant parameters from the STS and uses them against the management service to create an issuer. Let’s run the ACM tool to get the list of all issuers and verify that the new issuer has been correctly created. To do this, open a Powershell and run the following command.<br />Powershell<br />.acm.exe getall issuer<br />Figure 29<br />Get the issuer ID for the SAML issuer just created<br />Now that you created a new issuer, you need to retrieve its Id so that you can reference it when you will create the new access rules. Look for the serviceNamespaceSAML issuer, and copy the id: iss_XXXXXX attribute. To do this, select the id using the mouse and right click to place the content on the clipboard. Paste it on the LabsIntroToAccessControlServiceSourceEx02-UsingACSWithSAMLTokensBeginSetup.ps.txt file on the %adfsissuer% placeholder.<br />You already defined a scope for your service: since you want to create a new rule in that scope, you need to retrieve the scope id in order to reference it. Run the ACM tool to get the scopes and lookup the scope for the weatherforecast service. To do this, open a Powershell and run the following command.<br />Powershell<br />.acm.exe getall scope<br />Figure 30<br />Get the scope id for the weatherforecast<br />Look for the weatherforecast scope. Copy the id: scp_XXXXXX attribute. To do this, select the id using the mouse and right click to place the content on the clipboard. Paste it on the Setup.ps.txt file on the %scopeid% placeholder.<br />Your new access control rule will be based on the content of the SAML token coming from the ADFSv2 instance of your trusted partner. Let’s say that you know that employees in the security group “Pilots” are meant to have access to the getforecast3days method: all you need to do is creating a rule that issues an action claim with value “Get3DaysForecast” whenever an incoming claim of type http://schemas.xmlsoap.org/claims/Group and value “Pilots” is received from this issuer. Paste in powershell the command from the setup file.<br />Powershell<br />.acm.exe create rule -scopeid:%scopeid% -inclaimissuerid:%adfsissuer% -inclaimtype:http://schemas.xmlsoap.org/claims/Group -inclaimvalue:Pilots -outclaimtype:action -outclaimvalue:Get3DaysForecast -name:pilotsgroup3days<br />Figure 31<br />Creating a rule to allow calling Get3DaysForecast<br />This is all you need to do for configuring your ACS Service Namespace. Next, we will explore the changes that the client must introduce for successfully obtaining a SWT token from ACS when presenting a SAML token: once that happens, it is business as usual for everything else.<br />Task 2 - Create an “ADFSv2 ready” client<br />In this task you will add to the client the code that retrieves a SAML token from the local STS, send it to ACS, get a SWT token back and finally call the service transmitting the SWT token in an HTTP header.<br />In Solution Explorer, right click on the Client project and select Add Reference. Select the Microsoft.IdentityModel assembly and click OK. This will add the required assembly reference to use Windows Identity Foundation classes.<br />Figure 32<br />Adding a reference to Microsoft.IdentityModel<br />In Solution Explorer, Client project, double click on the Program.cs file. Add the following using directives at the beginning of the file for the code we'll be adding later. <br />(Code Snippet – Introduction to ACS Lab - Ex02 Client Usings)<br />C#<br />namespace Client<br />{<br /> using System;<br /> using System.Collections.Specialized;<br /> using System.IdentityModel.Tokens;<br /> using System.Linq;<br /> using System.Net;<br /> using System.ServiceModel;<br /> using System.ServiceModel.Security;<br /> using System.ServiceModel.Web;<br /> using System.Text;<br /> using System.Web;<br /> using Microsoft.IdentityModel.Protocols.WSTrust;<br /> using Microsoft.IdentityModel.Protocols.WSTrust.Bindings;<br />The last two namespaces are from Windows Identity Foundation: we will use the classes found there for retrieving the SAML token from the local STS.<br />Add the following constants in the body of the Program class.<br />(Code Snippet – Introduction to ACS Lab - Ex02 Client constants)<br />C#<br />public class Program<br />{<br /> private const string ServiceNamespace = " {insert service namespace here}" ;<br /> private const string AcsHostName = " accesscontrol.windows.net" ;<br /> private const string StsBaseAddress = " localhost/localsts" ;<br /> private const string StsPath = " Trust/13/UserName" ;<br /> public static void Main(string[] args)<br />Update the Service Namespace (the one you entered in Task 2 of the first exercise, step 4) used in the client ClientProgram.cs file. To do this, replace the ServiceNamespace constant in the code. <br />C#<br />private const string ServiceNamespace = " {insert service namespace here}" ;<br />Add the following lines of code to call the local STS and receive a SAML token in return. The SAML token will then be sent to ACS to be exchanged with a SWT token. <br />Note: The order of these instructions aim at helping you understand what it takes for a client to be able to use ACS, hence it follows a top-down approach. The code won’t compile at this point, but it eventually will, once you will have followed the instructions in the next 3 steps<br />(Code Snippet – Introduction to ACS Lab - Ex02 Client call STS)<br />C#<br />public static void Main(string[] args)<br />{<br /> string stsAddress = string.Format(" https://{0}/{1}" , StsBaseAddress, StsPath);<br /> string acsSTSAddress = string.Format(" https://{0}.{1}/WRAPv0.8" , ServiceNamespace, AcsHostName);<br /> string samlAssertion = GetSamlAssertion(stsAddress, acsSTSAddress);<br /> string acsToken = GetACSToken(samlAssertion);<br />Add the definition of the GetSamlAssertion method, which gets a token from the local STS. To do that, copy the following code at the end of the Program class.<br />(Code Snippet – Introduction to ACS Lab - Ex02 GetSamlAssertion Method)<br />C#<br />...<br />public static void Main(string[] args)<br />{<br /> ...<br />}<br />private static string GetSamlAssertion(string stsAddress, string acsStsAddress)<br />{<br /> WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(<br /> new WindowsWSTrustBinding(SecurityMode.TransportWithMessageCredential),<br /> new EndpointAddress(new Uri(stsAddress)));<br /> trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;<br /> RequestSecurityToken rst = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue, WSTrust13Constants.KeyTypes.Bearer);<br /> rst.AppliesTo = new EndpointAddress(acsStsAddress);<br /> rst.TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml2TokenProfile11;<br /> WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();<br /> GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken;<br /> return token.TokenXml.OuterXml;<br />}<br />The code here takes advantage of the object model for Windows Identity Foundation, and specifically of the WSTrustChannel class which makes it easy to send issuing requests to a WS-Trust STS.<br />The code in step 5 makes use of the GetACSToken method, which gets a token from ACS based on the SAML token. Add the definition of GetACSToken by coping the following code at the end of Program class. <br />(Code Snippet – Introduction to ACS Lab - Ex02 GetACSToken Method)<br />C#<br />public class Program<br />{<br /> ...<br />private static string GetSamlAssertion(string stsAddress, string acsStsAddress)<br /> ...<br /> private static string GetACSToken(string samlAssertion)<br /> {<br /> WebClient tokenClient = new WebClient();<br /> tokenClient.BaseAddress = string.Format(" https://{0}.{1}" , ServiceNamespace, AcsHostName);<br /> NameValueCollection values = new NameValueCollection();<br /> values.Add(" wrap_SAML" , samlAssertion);<br /> values.Add(" applies_to" , " http://localhost/weatherforecast" );<br /> byte[] responseBytes = tokenClient.UploadValues(" WRAPv0.8" , values);<br /> string response = Encoding.UTF8.GetString(responseBytes);<br /> return response<br /> .Split('&')<br /> .Single(value => value.StartsWith(" wrap_token=" , StringComparison.OrdinalIgnoreCase))<br /> .Split('=')[1];<br /> }<br />}<br />You can see how the method body here closely resembles the code we used in exercise 1 for performing a similar function with a symmetric key.<br />Add the code that will add the ACS token in the authorization HTTP header. To do that, add the following code right before calling the service.<br />(Code Snippet – Introduction to ACS Lab - Ex02 WRAP Header)<br />C#<br />using (new OperationContextScope(proxy as IContextChannel))<br />{<br /> string authHeaderValue = " WRAPv0.8" + " " + HttpUtility.UrlDecode(acsToken);<br /> WebOperationContext.Current.OutgoingRequest.Headers.Add(" authorization" , authHeaderValue);<br /> // call the service and get a response<br /> try<br /> {<br />...<br />Exercise 2: Verification<br />In order to verify that you have correctly performed all steps in exercise two, proceed as follows:<br />Right click on the Service project (in Solution Explorer), and select Debug | Start new instance to run the Service.<br />Figure 33<br />Service console<br />Right click on the Client project (in Solution Explorer), and select Debug | Start new instance to run the Client.<br />Figure 34<br />Client console showing the 3 days forecast but not the 10 days forecast because the user doesn’t have access to that.<br />Verify that the 3 days forecast is retrieved by looking at the console output. You'll also notice that the console displays an error on the following line. This is exactly in line with expectations: our rule granted this client access only to the Get3DaysForecast method , hence the attempt to access Get10DaysForecast was blocked with a (401) Unauthorized return code. This happened because the STS generated a SAML token with a group claim with value “Pilots” and we created an ACS rule that transform the group claim “Pilots” to Get3DaysForecast.<br />Note: as an optional exercise, you can try to create a second rule that would grant access to the Get10DaysForecast action for the “Pilots” group. Hint: you can follow the same procedure we illustrated in the verification section of exercise 1.<br />Exercise 2: Summary<br />In this exercise you have learned how to take advantage of ADFSv2 identities for managing access control to REST services. What made the scenario possible is the ability of the Access Control Service of processing SAML tokens issued by ADFSv2, transforming the claims from the incoming SAML assertion in authorization directives in the resulting SWT token.<br />Exercise 2 used the same service you developed in exercise 1: however the entire exercise 2 was completed without touching the code of the service. The service was already configured to trust SWT tokens issued by ACS, hence all it was needed for enabling a new service consumer was few calls to the ACS management service.<br />Summary<br />By completing this Hands-On Lab you have learned how to:<br />Modify your WCF services to take advantage of ACS for handling access control<br />Create and manage ACS Service Namespaces; work with token policies, issuers, scopes and rules<br />Invoke REST web services secured by ACS<br />Obtain tokens from ACS via SAML token, and use them to invoke REST web services<br />You can easily generalize what you have learned here to different scenarios or technologies: since all you need is an HTTP-capable client, it is easy to imagine how to apply the steps you have seen in this lab for requesting tokens from the widest range of platforms, devices and programming styles. As you have seen in the two exercises, once your REST services are configured to trust ACS it does not really matter which technology or credentials your clients will use: your services are decoupled from those changes.<br />When advanced capabilities are available, ACS is ready to take advantage of them: you can use what you learned in exercise 2 for taking advantage of your investment in Active Directory and ADFSv2 for extending to the REST world the sophisticated claims-based access control policies that until now were available only to WS-* stacks.<br />We hope that the lab inspired you to think about how the ACS can help you solve your access control challenges, and we invite you to experiment with the SDK and all the rest of the learning material Microsoft offers on this topic.<br />

×