<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Beside the Point</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/besidethepoint/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/besidethepoint/feed.xml</link>
    <description>A discussion of SharePoint-related concepts from multiple perspectives.</description>
    <lastBuildDate>Wed, 24 Feb 2016 11:04:10 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>AppFabric Caching (and SharePoint): Configuration and Deployment (Part 2)</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/appfabric-caching-and-sharepoint-configuration-and-deployment-part-2</link>
      <pubDate>Wed, 27 Mar 2013 14:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2013/03/27/appfabric-caching-and-sharepoint-configuration-and-deployment-part-2/</guid>
      <description><![CDATA[Part 1: AppFabric Caching and SharePoint: Concepts and ExamplesPart 2: AppFabric Caching (and...]]></description>
      <content:encoded><![CDATA[<p><a title="AppFabric Caching and SharePoint: Concepts and Examples (Part 1)" href="http://blogs.msdn.com/b/besidethepoint/archive/2013/03/27/appfabric-caching-and-sharepoint-1.aspx">Part 1: AppFabric Caching and SharePoint: Concepts and Examples</a><br /><a title="AppFabric Caching (and SharePoint): Configuration and Deployment (Part 2)" href="http://blogs.msdn.com/b/besidethepoint/archive/2013/03/27/appfabric-caching-and-sharepoint-2.aspx">Part 2: AppFabric Caching (and SharePoint): Configuration and Deployment</a></p>
<h1>The Distributed Cache Service</h1>
<p>SharePoint&rsquo;s distributed caches are hosted and maintained by the Distributed Cache Service, itself a thin wrapper over a Windows Server AppFabric cluster. Understanding SharePoint&rsquo;s Distributed Cache Service requires an understanding of AppFabric together with a few details on SharePoint&rsquo;s implementation. Most of the details here apply equally to non-SharePoint AppFabric cluster as well; just view SharePoint as a particular implementation example.</p>
<h2>AppFabric Physical Architecture</h2>
<p>Key details of AppFabric&rsquo;s physical architecture are described <a href="http://msdn.microsoft.com/en-us/library/hh334311(v=azure.10).aspx">here</a> and represented in this diagram (from the same location).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5861.AppFabric%20Physical%20Infrastructure.gif" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5861.AppFabric-Physical-Infrastructure.gif"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5861.AppFabric%20Physical%20Infrastructure.gif" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5861.AppFabric-Physical-Infrastructure.gif" alt="" border="0" /></a></p>
<p>In SharePoint&rsquo;s implementation, web and service applications are the &ldquo;Cache-enabled application servers (cache clients).&rdquo; The &ldquo;Cache Servers&rdquo; are SharePoint servers where the Distributed Cache Service Instance has been installed and enabled, and the &ldquo;Cluster configuration storage location&rdquo; is the CacheClusterConfig table in the SharePoint Configuration Database.</p>
<p>The CacheClusterConfig table in the Configuration Database stores configuration items as typed Key/Value pairs using a custom <a href="http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.applicationserver.caching.icustomprovider.aspx">ICustomProvider</a> implementation. The original values are XML snippets describing caches, cache hosts, and other properties. They are serialized and converted into byte arrays for storage, but most data can be deserialized and viewed using the Export-AFCacheClusterConfiguration cmdlet.</p>
<h3>AppFabric Cache Hosts in SharePoint</h3>
<p>Management of Distributed Cache Service Instances (AppFabric Cache Hosts) in SharePoint is different than management of most SharePoint service instances. Most service instances always remain installed on servers in the farm, whether online or not. These service instances are like Windows services, which are always installed on a server whether they&rsquo;ve been enabled or not. For example, the User Profile Sync Service Instance is typically only online and running on one server in the farm, but it&rsquo;s installed &ndash; and disabled - on all servers. To see a list of all service instances installed on a given server, both online and disabled, run the Get-SPServiceInstance cmdlet, using the &ndash;Server parameter to limit results to a particular server. The Services on Server page in Central Administration displays the same information.</p>
<p>Unlike other service instances, though, the Distributed Cache Service Instance should either be installed *and* online on a SharePoint server, or not installed at all. If the service instance is stopped (disabled) but not uninstalled, details about the associated Cache Host stay in the Cache Cluster Config store, which can cause problems.</p>
<p>For this reason, the Distributed Cache Service Instance should never be stopped via the Services on Server page in Central Administration or via Stop-SPServiceInstance in PowerShell. A special cmdlet, Remove-SPDistributedCacheServiceInstance, is available to stop *and* uninstall the local Distributed Cache Service Instance from a SharePoint server. This cmdlet, and its complement Add-SPDistributedCacheServiceInstance, should be used instead of Stop- and Start-SPServiceInstance for managing the local Distributed Cache Service Instance.</p>
<p>By default, the Distributed Cache Service Instance is installed on every SharePoint server when it&rsquo;s joined to a farm. If you prefer to not install the Distributed Cache Service Instance at join time, you can specify -SkipRegisterAsDistributedCacheHost when running the Connect-SPConfigurationDatabase or New-SPConfigurationDatabase cmdlets. Note that at least one server must be running the Distributed Cache Service Instance for the farm to function properly.</p>
<p>For all AppFabric clusters, a simple command for listing all known cache hosts in the cluster is Get-AFCacheHostStatus. Don&rsquo;t forget to run Connect-AFCacheClusterConfiguration before running other AppFabric cmdlets. To retrieve a list of SharePoint servers running the Distributed Cache Service Instance, you can run the following PowerShell command:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-SPServer | ? {($_.ServiceInstances | % TypeName) -contains 'Distributed Cache'} | % Address</span></p>
<p>We&rsquo;ll discuss more details about cache hosts soon, but first let&rsquo;s discuss AppFabric&rsquo;s logical infrastructure.</p>
<h2>AppFabric Logical Infrastructure</h2>
<p>Details regarding the logical infrastructure of an AppFabric cluster are provided <a href="http://msdn.microsoft.com/en-us/library/hh351438(v=azure.10).aspx">here</a> and in this diagram (from the same location):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/2437.AppFabric%20Logical%20Infrastructure.gif" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/2437.AppFabric-Logical-Infrastructure.gif"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/2437.AppFabric%20Logical%20Infrastructure.gif" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/2437.AppFabric-Logical-Infrastructure.gif" alt="" border="0" /></a></p>
<p>The basic logical entity in an AppFabric Cache Cluster is a Named Cache (frequently just called a Cache). A Named Cache is a container for cached objects. The ten SharePoint caches listed before are each AppFabric Named Caches. As illustrated here, Named Caches span all hosts in the cluster, distributing items for storage across allocated memory on all servers; however, cached items within a Named Cache are stored only once (by default). This is an important consideration when planning cache infrastructure, so let&rsquo;s spell it out again: by default (and in SharePoint), cached items in an AppFabric Named Cache are stored only once across the entire cluster. If the cache host storing that cached item crashes or is shutdown non-gracefully, that item is no longer available in the cache.</p>
<p>In the previous paragraph we introduced cache items. Items are often collected and stored in a Region, which is a sub-collection of cached items within a specific Named Cache. Storing items in a shared region can make retrieval of the entire related collection easier. Like individual cached items, though, regions exist on only a single host in the cluster by default (and in SharePoint). So if the server hosting the region is lost, all items in the region are lost with it. Also, note that all items in the Region, and the Region itself, are stored on a single cache host.</p>
<p>Both individual cached items and regions can co-exist in the same named cache. I believe that in SharePoint all cached items are contained within regions.</p>
<p>To list all named caches and regions in a cluster, run <span style="font-family: 'courier new', courier; font-size: 10pt; background: #e5e5e5;">Get-AFCache | Format-Table &ndash;AutoSize</span>. For a list of all caches, run <span style="font-family: 'courier new', courier; font-size: 10pt; background: #e5e5e5;">Get-AFCache | Format-Table CacheName</span>.</p>
<p>With the infrastructure described, let&rsquo;s dive more deeply into configuration of caches and cache hosts.</p>
<h1>Cache Configuration Details</h1>
<p>As we consider configuration details for caches and cache hosts, our conversation will be dominated by memory management, resiliency, and availability issues. We&rsquo;ll discuss expiration and eviction of items, throttling of requests, and redundant storage. As before, we&rsquo;ll discuss concepts in general and use SharePoint as a specific example.</p>
<p>Later, we&rsquo;ll discuss configuration of cache hosts, but first, let&rsquo;s begin by discussing configuration of individual caches.</p>
<p>To view common configuration details for individual caches, run the following command:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-AFCache | % {Get-AFCacheConfiguration -CacheName $_.CacheName}</span></p>
<p>Output for the ViewState cache is displayed here:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">CacheName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: DistributedViewStateCache_f3bd4763-f482-4bb8-a5a5-f40806460bdd<br />TimeToLive&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 10 mins<br />CacheType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Partitioned<br />Secondaries&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<br />MinSecondaries&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<br />IsExpirable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<br />EvictionType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: LRU<br />NotificationsEnabled&nbsp;&nbsp;&nbsp;&nbsp; : False<br />WriteBehindEnabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<br />WriteBehindInterval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 300<br />WriteBehindRetryInterval : 60<br />WriteBehindRetryCount&nbsp;&nbsp;&nbsp; : -1<br />ReadThroughEnabled&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<br />ProviderType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<br />ProviderSettings&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {}</span></p>
<p>The meanings of each of these properties is as follows.</p>
<ul>
<li><strong>CacheName</strong>: The internal name of the cache.</li>
<li><strong>TimeToLive</strong>: The default time span until expiry for cached items. Note that this can be overridden for any individual item, and in SharePoint there are different standard TTLs used for items in each named cache, as in the below table. Time until expiry has an important impact on eviction and memory management which will be discussed in the section on cache host configuration.</li>
</ul>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 200px;" /><col style="width: 100px;" /><col style="width: 200px;" /></colgroup>
<tbody valign="top">
<tr style="background: #4f81bd; color: #ffffff;">
<td><strong>Cache Name</strong></td>
<td><strong>TTL</strong></td>
<td><strong>Configuration Location</strong></td>
</tr>
<tr>
<td>ActivityFeed</td>
<td>168 hours</td>
<td>UserProfileApplication.FeedCacheTTLHours</td>
</tr>
<tr>
<td>ActivityFeedLMT</td>
<td>168 hours</td>
<td>UserProfileApplication. FeedCacheLastModifiedTimeTtlDeltaHours</td>
</tr>
<tr>
<td>LogonToken</td>
<td>10 hours</td>
<td>SPSecurityTokenServiceManager.WindowsTokenLifetime</td>
</tr>
<tr>
<td>ServerToAppServerAccessToken</td>
<td>24 hours</td>
<td>(hard coded)</td>
</tr>
<tr>
<td>ViewState</td>
<td>31 minutes</td>
<td>SPWebApplication.FormDigestSettings.Timeout + 1</td>
</tr>
<tr>
<td>Search</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>SecurityTrimming</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Default</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Access</td>
<td>1 hour</td>
<td>(hard coded)</td>
</tr>
<tr>
<td>Bouncer</td>
<td>1 hour</td>
<td>(hard coded)</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>CacheType</strong>: How data is stored in the cache&rsquo;s storage medium. Partitioned is the only option.</li>
<li><strong>Secondaries</strong>: How many additional replicas of cached data are to be stored. Additional replicas provide redundancy and resiliency for cached items, as replicas are always stored on a different storage node. This is always 0 in SharePoint, where high availability is not currently supported.</li>
<li><strong>MinSecondaries</strong>: The minimum number of secondaries which must be online to allow writing to the cache. By default, it&rsquo;s the same as the number of secondaries configured for the cache. Always 0 in SharePoint, where there are no secondaries.</li>
<li><strong>IsExpirable</strong>: Whether items in the cache are to be evicted after their TTL passes. Always True for SharePoint caches.</li>
<li><strong>EvictionType</strong>: The algorithm used to evict non-expired items when a cache&rsquo;s high watermark is passed. Can be set to LRU (Least Recently Used) or None. For most caches in SharePoint, this is set to LRU. For the ActivityFeedLMT cache, this is set to None. See the section on cache host configuration for details on eviction.</li>
<li><strong>NotificationsEnabled</strong>: Whether the cache will notify subscribers when cached items are changed or deleted. Always False in SharePoint caches.</li>
<li><strong>Read-Through and Write-Behind properties</strong>: The remaining properties specify details on Read-Through and Write-Behind for the cache. For details on RTWB concepts, see <a href="http://msdn.microsoft.com/en-us/library/hh377669(v=azure.10).aspx">this MSDN article</a>. SharePoint caches don&rsquo;t utilize RTWB.</li>
</ul>
<p>Most SharePoint caches have the same configuration. However, run this command to note that the ActivityFeedLMT cache has an EvictionType of None.</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-AFCache | % {Get-AFCacheConfiguration -CacheName $_.CacheName} | Format-Table CacheName, EvictionType</span></p>
<p>Note that there are no quota-related properties specified at the cache level for SharePoint caches, or by default for any caches.</p>
<p>You may want to know how many items are stored and how much memory is in use for individual caches. For specific stats about each cache, run this command:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-AFCache | % {<br />&nbsp; &nbsp; $CacheName = $_.CacheName<br />&nbsp; &nbsp; Get-AFCacheStatistics -CacheName $CacheName | Add-Member -MemberType NoteProperty -Name 'CacheName' -Value $CacheName -PassThru<br />}</span></p>
<p>I&rsquo;ve added a little formatting and cleanup to get detailed information about each cache together with its name. You could pipe the output from this command to Export-Csv to create a short report. Typical output is shown here:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">CacheName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : DistributedLogonTokenCache_f3bd4763-f482-4bb8-a5a5-f40806460bdd<br />Size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 36864<br />ItemCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 6<br />RegionCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 6<br />RequestCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 55<br />ReadRequestCount&nbsp; : 26<br />WriteRequestCount : 14<br />MissCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 32<br />IncomingBandwidth : 96924<br />OutgoingBandwidth : 880</span></p>
<p>Having illustrated key elements on configuring individual caches, let&rsquo;s move on to configuring cache hosts.</p>
<h1>Cache Host Configuration Details</h1>
<p>To retrieve configuration details for cache hosts, run the following command, which retrieves information about each host currently in the cluster:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-AFCacheHostStatus | % {<br />&nbsp; &nbsp; $Status = $_.Status<br />&nbsp; &nbsp; Get-AFCacheHostConfiguration -ComputerName $_.HostName -CachePort $_.PortNo |<br />&nbsp; &nbsp; &nbsp; &nbsp; Add-Member -MemberType NoteProperty -Name 'Status' -Value $Status -PassThru<br />} | Format-List -Property *</span></p>
<p>I start this command with Get-AFCacheHostStatus since it returns all hosts in the cluster without further parameters necessary, unlike Get-AFCacheHostConfiguration. Note however that Get-AFCacheHostStatus attempts to ping each host in the cluster in order to report on status, and the timeout for this ping is 10 seconds. For a faster version of this command, at least for SharePoint servers, try this:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; $SPDCServers = Get-SPServer | ? {($_.ServiceInstances | % TypeName) -contains 'Distributed Cache'} | % Address<br />PS:&gt; $SPDCServers | % {Get-AFCacheHostConfiguration -ComputerName $_ -CachePort 22233}</span></p>
<p>Of course, you won&rsquo;t get a Status without Get-AFCacheHostStatus.</p>
<p>Output from the first command will look like the following:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Up<br />HostName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SERVER09.gavant.local<br />ClusterPort&nbsp;&nbsp;&nbsp;&nbsp; : 22234<br />CachePort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 22233<br />ArbitrationPort : 22235<br />ReplicationPort : 22236<br />Size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 600<br />ServiceName&nbsp;&nbsp;&nbsp;&nbsp; : AppFabricCachingService<br />HighWatermark&nbsp;&nbsp; : 99<br />LowWatermark&nbsp;&nbsp;&nbsp; : 90<br />IsLeadHost&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True</span></p>
<p>Let&rsquo;s describe the meaning of each of these properties:</p>
<ul>
<li><strong>Status</strong>: If the host responds to a standard ICMP ping within 10 seconds, this reports the status of the AppFabric service on that server. May be: {Up, Down, Starting, Stopping, ShuttingDown, Unknown}. This is the output from Get-AFCacheHostStatus.</li>
<li><strong>HostName</strong> and <strong>ServiceName</strong>: Host and service name.</li>
<li><strong>CachePort</strong>: The main port for public (external) communication with the cache host and cluster. Must be open to incoming client traffic.</li>
<li><strong>ClusterPort</strong>, <strong>ArbitrationPort</strong>, and <strong>ReplicationPort</strong>: Used for internal data management communication amongst the hosts in the cluster. Must be open between servers.</li>
<li><strong>Size</strong>: The amount of memory in MB to be allocated for live cached items. Note that actual memory used by the process will be significantly greater than this amount, and will be discussed later.</li>
<li><strong>LowWatermark</strong>: Percentage of memory usage (from Size) when *expired* items are removed (evicted) from cache if expiration is enabled.</li>
<li><strong>HighWatermark</strong>: Percentage of memory usage (from Size) when *all* items may be removed (evicted) from cache if eviction is enabled.</li>
<li><strong>IsLeadHost</strong>: Whether this host is a lead host for cluster management. Not used in SharePoint.</li>
</ul>
<p>Now that we&rsquo;ve briefly discussed each of these properties, let&rsquo;s dive deeper into their implications.</p>
<h2>Eviction, Expiration, and Watermarks</h2>
<p>The time has come to explain eviction, expiration, and watermarks. In a nutshell, the goal of the AppFabric service is to maintain the memory a cache host uses to store cached items between the low watermark and high watermark configured for that cache host. Every one second (by default), current memory usage for the host is checked against the Size and computed high and low watermark values for the host; based on the results, the following memory management algorithm is implemented.</p>
<ul>
<li><strong>Low Watermark not yet reached</strong>. No items are removed from the cache, even if expired.</li>
<li><strong>Low Watermark reached, High Watermark not reached</strong>. Expired items are evicted, but non-expired items are not.</li>
<li><strong>High Watermark reached</strong>. Expired and non-expired items are evicted until low watermark is reached.</li>
</ul>
<p>This is shown graphically here:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5488.HWM-LWM.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5488.HWM_2D00_LWM.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5488.HWM-LWM.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5488.HWM_2D00_LWM.png" alt="" border="0" /></a></p>
<p>If and when less than 15% (by default) of server memory remains, an eviction run is initiated regardless of the local cache host&rsquo;s watermark and size settings. That is, even though the host is not using all of its allowed memory, if available memory on the server is below 15% of the total physical memory, a full eviction run will begin, as if the high watermark had been passed.</p>
<p>Note that caches specify whether they will be subject to expiration and eviction via the IsExpirable and EvictionType properties, as discussed in the previous section. If either of these excludes the cache from eviction, corresponding cached items will not be removed. For example, if IsExpirable is True and EvictionType is None (as it is for the Activity Feed LMT cache in SharePoint), expired items will be removed once the cache reaches its low watermark, but non-expired items will never be removed. As a result, if no items in the cache are expired, nothing will be removed.</p>
<p>If throttling is enabled (see below) the cache would eventually be write-throttled and no further items would be added till some items expired or were removed. However, throttling is not enabled by default in AppFabric for Windows Server and *I believe* that in this case the cache will continue to grow beyond its allotted size, governed only by the algorithm described above. Test and consider this when planning your own cache and host configurations.</p>
<h2>Cache Statistics</h2>
<p>Since the current amount of memory in use by the cache is so important, you&rsquo;ll be interested in the commands which return a snapshot of current usage. As before, you have a couple options for retrieving information about all servers in the cluster, one using the Get-AFCacheHostStatus to iterate through all hosts, and one by finding all configured service instances in SharePoint. They are as follows:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-AFCacheHostStatus | % {<br />&nbsp; &nbsp; $ServerName = $_.HostName<br />&nbsp; &nbsp; Get-AFCacheStatistics -ComputerName $_.HostName -CachePort $_.PortNo | Add-Member -MemberType NoteProperty -Name 'ServerName' -Value $ServerName -PassThru<br />} | Format-List -Property *</span>&nbsp;</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; $SPDCServers = Get-SPServer | ? {($_.ServiceInstances | % TypeName) -contains 'Distributed Cache'} | % Address<br />PS:&gt; $SPDCServers | % {<br />&nbsp; &nbsp; $ServerName = $_<br />&nbsp; &nbsp; Get-AFCacheStatistics -ComputerName $_ -CachePort 22233 | Add-Member -MemberType NoteProperty -Name 'ServerName' -Value $ServerName -PassThru<br />}</span></p>
<p>And typical output looks like this:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">ServerName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SERVER09<br />Size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 51200<br />ItemCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 18<br />RegionCount&nbsp;&nbsp;&nbsp;&nbsp; : 13<br />NamedCacheCount : 10<br />RequestCount&nbsp;&nbsp;&nbsp; : 393<br />MissCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 66</span></p>
<p>Here, the SERVER09 cache host has allocated 51200 bytes (about 51K) to cached items. Since the allowed size for this cache host is much higher than 51K, neither expiration or eviction is necessary on this server, assuming at least 15% of the server&rsquo;s physical memory is free.</p>
<h2>Throttling</h2>
<p>According the <a href="http://msdn.microsoft.com/en-us/library/hh334407(v=azure.10).aspx">this MSDN article</a>, AppFabric for Windows Server is subject to throttling based on percentage of server memory in use and percentage of AppFabric service memory in use. However, in my investigations I&rsquo;ve found that throttling is disabled by default in AppFabric for Windows Server, and SharePoint does not change the defaults. This means that even though no memory from the cache host&rsquo;s allowed size remains, or even if no memory on the entire server remains, the system will continue to try to serve requests and allocate memory for cached items.</p>
<p>I&rsquo;ll continue to investigate Throttling and update this section if I find other information. Please let me know if your testing reveals different behavior than I&rsquo;ve described.</p>
<p>With all this discussion of memory algorithms and calculations, you won&rsquo;t be surprised to learn that memory overcommitment schemes employed by virtualization hypervisors, such as Hyper-V&rsquo;s dynamic memory, are not supported with SharePoint, and not recommended with AppFabric in general.</p>
<h1>SharePoint Cache Service Details</h1>
<p>Now that we&rsquo;re explained most aspects of AppFabric cache and cache host configuration, let&rsquo;s explore some of the defaults used for SharePoint cache hosts, and some recommendations.</p>
<h2>Cache Host Size for SharePoint Hosts</h2>
<p>There are two points during setup of a Distributed Cache Service Instance on a SharePoint server when the local cache host configuration comes into play: at <strong>service installation</strong> (e.g. during Farm Join or when running Add-SPDistributedCacheServiceInstance) and at <strong>service provisioning</strong> (e.g. immediately following service installation, or when calling Start-SPServiceInstance).</p>
<p>At <strong>service installation</strong> time, the Size property for the local cache host is set to 5% of the total physical memory of the host. For example, if 16GB of physical RAM are installed on the host at installation time, the size of the local cache host will be set to 800MB. Note that this value could be different on each SharePoint server if they have different amounts of physical RAM at installation time. Note also that this value won&rsquo;t automatically change if the amount of physical RAM allocated to the server changes.</p>
<p>At <strong>service provisioning</strong> time, SharePoint checks that the amount of available physical memory in the server is at least 100MB more than the allowed size for the cache host. So if, as in the above example, the cache host size is set to 800MB, at least 900MB of physical RAM must be available at provisioning time, or the service will fail to start.</p>
<p>These default values may not be appropriate for your environment. In the next section we&rsquo;ll discuss options for changing them.</p>
<h2>Changing Cache Host Size for SharePoint</h2>
<p>There are two options for modifying cache host size for SharePoint AppFabric servers. Both require shutting down the entire cluster (all cache hosts).</p>
<p>The first utilizes AppFabric&rsquo;s own PowerShell cmdlets. First, run Stop-AFCacheCluster to shut down all hosts in the cluster, then on each cache host run Set-AFCacheHostConfiguration -CacheSize &lt;NewSizeInMB&gt; to specify a new cache size. Don&rsquo;t forget to run Start-AFCacheCluster to restart all hosts in the cluster. You can also specify different high and low watermarks with the Set-AFCacheHostConfiguration cmdlet.</p>
<p>Advantages of the native AppFabric cmdlet approach are that 1) all hosts in the cluster are stopped immediately (not gracefully), 2) you can specify different cache sizes for each host, and 3) you can configure low and high watermarks if necessary.</p>
<p>The second approach is to use SharePoint&rsquo;s Update-SPDistributedCacheSize cmdlet. This takes only one&nbsp;parameter, -SizeInMB. It shuts down all hosts in the cache cluster, updates the cache size for each of them, then restarts them all.</p>
<p>Disadvantages of the SharePoint cmdlet are that it 1) shuts down all but the last host in the cluster gracefully and 2) sets all cache hosts to the same size. Graceful shutdown takes much longer than immediate shutdown, since all cached items must first be moved to a different host. Yet since the entire cluster is to be shut down, graceful shutdown is not helpful here.</p>
<p>Hopefully, Microsoft will address the graceful shutdown issue in the future, and setting all servers to the same memory size may be appropriate in your farm. If these items aren&rsquo;t concerns for you, I&rsquo;d recommend using the SharePoint-specific cmdlet, as this will always command more respect if and when you need support.</p>
<p>Whether you use AppFabric or SharePoint cmdlets to modify cache host size, note that if you uninstall and reinstall the Distributed Cache Service Instance on a server (i.e. by running Remove-SPDistributedCacheServiceInstance and then Add-SPDistributedCacheServiceInstance) the cache host size will be reset to the default (5% of physical memory at time of installation). If removing and adding the cache service instance is part of your maintenance cycles, make sure to also modify the cache size afterwards if needed.</p>
<p>We&rsquo;ve discussed many concepts relevant to AppFabric infrastructure and planning. Now let&rsquo;s focus on a couple specific applied details.</p>
<h1>Planning Server Memory and Cache Host Size</h1>
<p>A key detail in AppFabric Cache Service planning is that the actual memory usage of the DistributedCacheService process will be significantly larger than the size allocated in the cache host configuration. <a href="http://msdn.microsoft.com/en-us/library/hh334304(v=azure.10).aspx">This MSDN article</a> states that at least twice the amount of memory specified for the cache host will be used by the process due to memory management algorithms. Run this command for a quick review of how much memory the process is actually consuming:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-Process DistributedCacheService | fl *64*</span></p>
<p>At the time I ran this command, Get-AFCacheStatistics reported my cache host size as 9216 bytes. The process&rsquo;s Working Set, however, was 584118272 bytes (almost 600MB). This is of course much more than twice the used amount of RAM; my assumption is that there is always a base level of memory overhead no matter how small the actual caches may be.</p>
<p>The key takeaway here is that if you have a certain amount of memory to allocate for AppFabric, the size specified for the host configuration should be half of that. For example, if I intend to allocate 16GB of physical memory for AppFabric, the size specified in the host configuration should be 8GB.</p>
<p>Also in <a href="http://msdn.microsoft.com/en-us/library/hh334304(v=azure.10).aspx">that article</a>, it&rsquo;s recommended not to allocate more than 16GB for the AppFabric server (and corresponding 8GB for the cache host configuration). If the cache host&rsquo;s size is larger than 16GB/8GB, garbage collection could take long enough to cause a noticeable interruption for clients.</p>
<p>A common recommendation is to spec AppFabric servers with 16GB of physical RAM, and set the cache host size to 7GB. With this arrangement, you can expect about 14GB to be used by the AppFabric process, leaving 2GB for other server processes on the host.</p>
<p>Let&rsquo;s wrap up by discussing a couple additional considerations specifically relevant to SharePoint&rsquo;s AppFabric implementation.</p>
<h1>Other Considerations for AppFabric in SharePoint</h1>
<h2>High Availability</h2>
<p>This one is easy - SharePoint (as ofMarch 2013) does not provide any high availability for its caches. As briefly discussed above, this means that each item and region in SharePoint&rsquo;s named caches exists only once across all the memory in the cluster. If the server where that item has been stored in memory is lost or shut down ungracefully, that cached item will be lost. As discussed at the very beginning of this post, this is generally not a problem for cached items because they are authoritatively stored elsewhere. Nevertheless, there are a couple things to keep in mind.</p>
<p>First, retrieving cached items all over again involves a performance hit, the very hit the caches are intended to help avoid. There could be interruptions and delays while the caches are being refilled. For example, if the ActivityFeed cache is lost, users may not see all recent updates in their Newsfeed, or may see the &ldquo;We&rsquo;re still gathering the news&rdquo; message as the cache is repopulated.</p>
<p>For the ActivityFeed and ActivityFeedLMT cache, there are two PowerShell cmdlets to manually begin repopulation of the caches before users actually request data. These are Update-SPRepopulateMicroblogLMTCache and Update-SPRepopulateMicroblogFeedCache. In situations where maintenance leads to loss of these caches, plan to run these cmdlets immediately afterwards to repopulate data manually.</p>
<p>A second concern when cached data in SharePoint is lost is that some items in SharePoint are *only* stored in the cache; specifically, updates regarding followed documents are only stored in the cache (as of March 2013). If these cached items are lost they won&rsquo;t be able to be regenerated and will no longer appear in users&rsquo; feeds.</p>
<p>To avoid losing items from the cache and/or having to retrieve them again, you can use the Stop-SPDistributedCacheServiceInstance cmdlet with the -Graceful switch. This will move all cached items from the local cache host to other cache hosts in the cluster. For this to be effective, there must be space on the other servers to accommodate these items. Also note that if shutting down the entire cluster, such as to change the cache host size, there&rsquo;s no way to avoid losing all of the caches and items. Plan accordingly.</p>
<h2>Other Caches in SharePoint&rsquo;s Deployment</h2>
<p>One last detail is that Microsoft has stated that additional named caches should not be deployed to the SharePoint AppFabric cluster (i.e. by using the New-AFCache cmdlet). If you need a cache for a custom solution, you&rsquo;ll need to deploy a separate AppFabric cluster (or server) and create the cache there. Then point your solution at the external AppFabric cluster. There&rsquo;s also no supported way to add your own cached items to SharePoint&rsquo;s named caches.</p>
<h1>Conclusion</h1>
<p>This concludes our presentation on AppFabric and SharePoint&rsquo;s Distributed Cache Service. I hope it provides both SharePoint and AppFabric administrators with a deeper understanding and greater ability to manage distributed cache clusters.</p>]]></content:encoded>
    </item>
    <item>
      <title>AppFabric Caching and SharePoint: Concepts and Examples (Part 1)</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/appfabric-caching-and-sharepoint-concepts-and-examples-part-1</link>
      <pubDate>Wed, 27 Mar 2013 14:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2013/03/27/appfabric-caching-and-sharepoint-concepts-and-examples-part-1/</guid>
      <description><![CDATA[Part 1: AppFabric Caching and SharePoint: Concepts and ExamplesPart 2: AppFabric Caching (and...]]></description>
      <content:encoded><![CDATA[<p><a title="AppFabric Caching and SharePoint: Concepts and Examples (Part 1)" href="http://blogs.msdn.com/b/besidethepoint/archive/2013/03/27/appfabric-caching-and-sharepoint-1.aspx">Part 1: AppFabric Caching and SharePoint: Concepts and Examples</a><br /><a title="AppFabric Caching (and SharePoint): Configuration and Deployment (Part 2)" href="http://blogs.msdn.com/b/besidethepoint/archive/2013/03/27/appfabric-caching-and-sharepoint-2.aspx">Part 2: AppFabric Caching (and SharePoint): Configuration and Deployment</a></p>
<p>To assist with scaling and performance, SharePoint 2013 utilizes Windows Server AppFabric to maintain an in-memory cache of frequently-used data. While this in-memory cache achieves its goals and does improve scalability, it also adds another service to maintain to SharePoint&rsquo;s long list of supporting elements. In this article I&rsquo;ll summarize and distill information on AppFabric from across MSDN and TechNet and add a SharePoint tinge to it to help you prepare for and manage SharePoint&rsquo;s Distributed Cache service.</p>
<p>If you&rsquo;re an AppFabric admin, there&rsquo;s a lot of detail here that will help you as well. Just view SharePoint&rsquo;s AppFabric cluster and caches as an example of an AppFabric implementation.</p>
<p>We&rsquo;ll begin with the fundamentals to ensure we all share the same basic understandings.</p>
<h1>What is a cache?</h1>
<p>As I said, we'll start with the fundamentals :). A cache is a local, non-authoritative copy of data created and/or stored authoritatively elsewhere. Because retrieval of the data from its authoritative source is an expensive operation, instead of retrieving it freshly each time it&rsquo;s needed, previous copies of the data are retained and used for subsequent needs.</p>
<p>Reasons to avoid the authoritative operation include:</p>
<ul>
<li><strong>Network latency and delays</strong>. The data may be stored across relatively slow network links or require multiple intermediate hops to be retrieved. Rather than retrieving it for each request, a copy is stored nearby. An example of this in SharePoint is the BLOB cache; BLOBs from content databases are stored locally on front-end servers to avoid the need for further network trips to SQL.</li>
<li><strong>User mediation required</strong>. The user may have to participate in retrieving the data, such as via authentication prompts and browser redirects. Imagine if a user had to undergo the three-legged process of WS-Federation authentication for every request! Far simpler to cache a security token and rely on it for subsequent requests.</li>
<li><strong>Processing power required</strong>. The authoritative data may be generated locally, but a relatively high amount of processing power is needed to generate it. Instead of regenerating the data for each request, a copy of the processed data is retained for a while. A good example of this is ASP.NET&rsquo;s page output cache, which avoids ASP.NET having to fully process each request. A SharePoint-specific example is the SiteData Object Cache, wherein the results of cross-site list item queries are cached and used for subsequent requests to avoid the processing hit of running the query again.</li>
<li><strong>Authoritative source not consistently available</strong>. Perhaps the client or server cannot be consistently connected. If the client depended on always communicating with the data&rsquo;s authoritative source, it wouldn&rsquo;t be able to work when not connected. Caching the data locally mitigates this. SkyDrive Pro is an example of offline caching.</li>
</ul>
<p>It&rsquo;s important to call out that in all cases of caching, the expense of generating or retrieving the authoritative data is traded for greater memory requirements where the data is cached. Either RAM (short term) or hard disk (long term) memory will need to be allocated for the data.</p>
<h1>Implications of Caching</h1>
<p>The defining characteristic of a cache is that it isn&rsquo;t the authoritative source of the data. This leads to some important ramifications:</p>
<ol>
<li>Cached data may not be completely current. Results and data may have changed at the authoritative source and not yet be reflected in the cached data. This effects many cache configuration choices, such as how long the cached data should be relied upon. There may be cases where the cache should be completely bypassed, or when a cache shouldn&rsquo;t be used at all.</li>
<li>Caches generally don&rsquo;t need to be as resilient as the authoritative source. If cached data is lost, it can be retrieved or regenerated, albeit at an expense. Again, this effects decisions about cache configuration, such as redundancy and high availability. Since the cache can be regenerated with a minor performance hit, secondary copies and resiliency may be less important. Then again, they may be quite important, depending on how difficult regenerating the data could be.</li>
</ol>
<p>Having discussed shared characteristics of all caches, let&rsquo;s discuss some of SharePoint&rsquo;s caching mechanisms.</p>
<h1>Caches in SharePoint</h1>
<p>Caches abound in SharePoint &ndash; from disk-based caches of data from databases, to in-memory caches of processed queries and pages, to caches of properties retrieved from internal and external services. The Distributed Cache service in SharePoint and its AppFabric underpinnings are just one example of a SharePoint cache. To emphasize this point, let&rsquo;s begin by discussing some caches that have been around in SharePoint for a little while already.</p>
<p>Some common SharePoint caches include the BLOB cache, the ASP.NET page output cache, and the User Profile Service properties cache. We&rsquo;ll describe them one by one to help you understand caches and their implications better.</p>
<h2>BLOB Cache</h2>
<p>Or Binary Large Object Cache. My wife always perks up when I bring up the cash blobs in SharePoint, at least till I start explaining them. If you&rsquo;re reading this, you&rsquo;re more interested in knowing that when a user requests a byte-stream object in SharePoint, such as a document or an image, and the item is retrieved from a SQL database to be sent to the user, the BLOB cache stores this object on the local file system of web servers. This avoids the need&nbsp;to retrieve the data from SQL again for subsequent requests for the same object.</p>
<p>Using this familiar example, let&rsquo;s call out some of the advantages and disadvantages of the Blob Cache.</p>
<ol>
<li>The key advantage is avoiding the network latency of retrieving large files from across the network from SQL. In exchange for avoiding this trip, additional disk space is needed on the front-end servers. Note also that if the speed of retrieving data from disk isn&rsquo;t faster than retrieving data from across the network, there&rsquo;s limited benefit to this cache.</li>
<li>Data could be stale. A user sending a request to one front-end server might update the large file, but a second user working on a different server could still be served an older copy cached on that server. There are mechanisms in place to check for updated files and deprecate the cached version, but there will always be points in time where the cached data is stale.</li>
<li>The data is cached separately on each server. If a user requests the BLOB via one front-end server, the BLOB will be cached only there. If another user requests the same BLOB via another front-end server, that server will have to retrieve the BLOB itself, and store it again in its own file system. Note that AppFabric and the Distributed Cache are designed largely to mitigate this issue of cache locality (though not for the BLOB cache).</li>
<li>The cache is less resilient than the database. If you lose the cached blobs, no critical data loss will occur. As such, you only back up and provide high availability for the database, not the cache.</li>
</ol>
<p>Now let&rsquo;s move on to the ASP.NET Page Output Cache.</p>
<h2>ASP.NET Page Output Cache</h2>
<p>Another well-known cache in SharePoint is the ASP.NET Page Output cache, which is actually a standard ASP.NET feature. It provides a good example of an in-memory cache designed to save processing power. Every incoming HTTP request causes activity and requires CPU cycles for ASP.NET&rsquo;s HTTP handlers. The Page Output cache allows the results of this activity to be stored and re-used, avoiding the need for repeated processing of identical or similar requests. While for a request or two the performance gains may be small, for sites processing hundreds or thousands of requests, avoiding repeated processing saves a lot of resources and vastly improves scalability.</p>
<p>Let&rsquo;s call out advantages and disadvantages of the Page Output cache.</p>
<ol>
<li>The key advantage is avoiding the use of processing power to process identical requests many times. In exchange for avoiding this CPU usage, memory is required to store the page output.</li>
<li>Data could be stale. If the page&rsquo;s processing retrieves data from a web service or some other changing resource, that data might have changed since the page was last processed, but the changes won&rsquo;t be reflected in the cached page. An example I recently came across is the time zone entries in Wikipedia (e.g. <a href="http://en.wikipedia.org/wiki/Eastern_Time_Zone">US Eastern Time Zone</a>). There&rsquo;s a &ldquo;current time&rdquo; row in the information box on the page, but the time is usually stale. You can click &ldquo;Refresh the Clock,&rdquo; which apparently forces Wikipedia&rsquo;s servers to discard the cached version of the page and generate a new one.</li>
<li>Data could be inaccurate. This is a tricky one and one which a software architect would do everything to avoid. When data is processed for the sake of one request and then served to fulfill another, there&rsquo;s a possibility that the context of the latter request isn&rsquo;t exactly the same as the former. Generally, you&rsquo;d account for significant changes of context by caching different versions of the data, such as one for authenticated users and one for anonymous users. There remains a possibility that differences in context could slip through, though.</li>
<li>More RAM is required. This of course depends on how many requests are cached. Each one requires its own space in RAM (or perhaps hard disk). CPU resources have been saved, but if memory isn&rsquo;t accordingly increased the exchange might not be worthwhile.</li>
</ol>
<p>Let&rsquo;s go through one more example of a cache in SharePoint, one which probably is not so familiar.</p>
<h2>User Profile Application Proxy Settings Caches</h2>
<p>User Profile Service Application (UPA) Proxies retrieve configuration details from their associated UPAs and databases and cache those details in several per-process in-memory caches. Settings stored in these caches include the URLs for MySite portals, Following limits, UPA sync configuration (e.g. whether to sync inactive users), and Newsfeed settings, among many others. Details such as the expiration time span (TTL) and max size for these caches can be viewed with the following PowerShell commands:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; $UPAProxy = Get-SPServiceApplicationProxy | ? TypeName -Match 'User Profile Service Application Proxy'<br />PS:&gt; $UPAProxy.Parent</span></p>
<p>The UPA proxy configuration settings caches are examples of caches meant to save the latency of network trips. After retrieving these properties from the associated UPA once, the UPA Proxy continues to rely on them for a period of time instead of requesting them again.</p>
<p>With UPA configuration details, being aware of the potential for stale data is important. For example, by default the Application Properties cache, which stores key configuration details for the UPA, only refreshes every 5 minutes. So if, for example, you configure your User Profile Sync job to sync inactive as well as active users (via <span style="font-family: 'courier new', courier; background: #e5e5e5; font-size: 10pt;">stsadm &ndash;o sync &ndash;ignoreisactive</span>), the setting may not be reflected in the cached properties for up to 5 minutes. If you have encountered situations where &ldquo;IgnoreIsActive&rdquo; didn&rsquo;t seem to be having an effect, perhaps you ran sync too soon after changing the property.</p>
<p>This concludes our presentation of three typical caches and how they&rsquo;re used in SharePoint. In the following table, I&rsquo;ve also highlighted where the cached data is stored. We&rsquo;ll focus on this aspect of caches next.</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="128">
<p><strong>Cache</strong></p>
</td>
<td valign="top" width="210">
<p><strong>Authoritative Source</strong></p>
</td>
<td valign="top" width="203">
<p><strong>Conserved Resource</strong></p>
</td>
<td valign="top" width="240">
<p><strong>Cache Location</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>BLOB Cache</p>
</td>
<td valign="top" width="210">
<p>Content Databases</p>
</td>
<td valign="top" width="203">
<p>SQL Requests (over network)</p>
</td>
<td valign="top" width="240">
<p>WFE Disk Drive</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>ASP.NET Page Output Cache</p>
</td>
<td valign="top" width="210">
<p>Processed ASP.NET Requests</p>
</td>
<td valign="top" width="203">
<p>CPU Usage (on WFE)</p>
</td>
<td valign="top" width="240">
<p>Web Process memory</p>
</td>
</tr>
<tr>
<td valign="top" width="128">
<p>UPA Settings Caches</p>
</td>
<td valign="top" width="210">
<p>UPA Web Services</p>
</td>
<td valign="top" width="203">
<p>WCF Requests (over network)</p>
</td>
<td valign="top" width="240">
<p>Web Process memory</p>
</td>
</tr>
</tbody>
</table>
<h1>Cache Data Storage Location</h1>
<p>By caching and reusing data, the consuming service subsequently saves the resources otherwise required to produce or retrieve that data again. But the scope of those savings depends on where the cached data is stored and what other elements of the service can access it. In each of the examples in the previous section, the scope of the cache is not service-wide. Not every element of the consuming service has access to the cached data; that is, not every process in the SharePoint farm has equal access to cached items. For the BLOB cache, only processes running on the same server that originally retrieved the BLOBs can access the cache; other servers still need to make a full SQL request and acquire the authoritative data. For the page output cache, each web process instance needs to generate the page once before being able to serve it, and cannot rely on the output page cache from other processes. And for the UPA settings cache, each web or service process which instantiates the UPA proxy needs to refill its own process-local caches.</p>
<p>The impact and resource savings of caching data can be scaled by expanding the scope of access to the cached data. If the processed ASP.NET page were accessible to all web worker processes in the farm, for example, many additional processing runs would be avoided, saving CPU cycles. In addition, if a single processed and cached copy of the page could be made easily accessible across the farm, memory needs would be reduced as well. Since in fact the output cache is per process, each process must process the request at least once (more CPU cycles required), and each process must allocate its own memory for the output page (more RAM required).</p>
<p>To address the need for wider scope and centralized storage of caches and cached items, centralized cache services are deployed. Instead of individual servers and processes retrieving and storing cached items locally and internally, they store them (and sometimes even retrieve them) via a centralized cache service. As a result, other servers and processes in the environment can access and benefit from the same cached data. To increase the scalability, availability, and redundancy of these cache services, they are usually deployed as distributed services, where multiple servers and processes present a single unified interface for storing and retrieving cached data. Sound familiar? We&rsquo;ve just described the role and purpose of the AppFabric Caching Service, or in SharePoint-specific parlance, the Distributed Cache Service.</p>
<p>To state it again explicitly, the role of the AppFabric Caching Service (in SharePoint: the Distributed Cache Service) is to provide a centralized, widely-accessible service for storage of cached data items. This central service improves performance and scalability of many SharePoint processes by multiplying the benefits of caching across all of SharePoint&rsquo;s servers and processes.</p>
<p>We&rsquo;ll clarify the role of a centralized, distributed cache service by describing the data stored in some of SharePoint&rsquo;s caches.</p>
<h1>Distributed Caches in SharePoint</h1>
<p>You can get a list of the distributed cache types used in SharePoint by running the following PowerShell command:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">[Enum]::GetNames( [Microsoft.SharePoint.DistributedCaching. Utilities.SPDistributedCacheContainerType])</span></p>
<p>The caches available as of this writing (March 2013) are listed in the following table. We&rsquo;ll focus here on just two of them for now: the LogonToken and ViewState caches.</p>
<table style="width: 285px;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="285">
<p>ActivityFeed</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>ActivityFeedLMT</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>LogonToken</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>ServerToAppServerAccessToken</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>ViewState</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>Search</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>SecurityTrimming</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>Access</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>Bouncer</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>Default</p>
</td>
</tr>
</tbody>
</table>
<h2>Logon Token Cache</h2>
<p>The LogonToken cache is the one you&rsquo;re likely to encounter first both practically, since it&rsquo;s used as soon as you hit your first SharePoint site, and in preparing for SharePoint deployment, since it obviates the need for affinity (sticky sessions) for WFE requests.</p>
<p>The process of logging on to SharePoint always culminates in creation of a session token which contains key details about the user, such as his or her username. Whether initial authentication uses Windows auth, Forms auth, or a SAML token issued by an external identity provider, the final result is this session token. To avoid the multiple steps involved in getting to this token, after it&rsquo;s created during initial logon, it&rsquo;s cached. Prior to SharePoint 2013, this cache was a server-local cache.</p>
<p>Having read the previous sections, you&rsquo;ll know that a cache which is stored locally to each server has the disadvantage of requiring the authentication process to be repeated again at other servers. Depending on the situation, this could result in a) a small performance hit, as in regeneration of a Windows-based token; b) more evident delays, as in the WS-Federation redirects for external identity providers; or c) additional user prompts and interference, such as requiring the user to choose an identity provider and provide credentials again. To get around these issues, a common practice was to limit sessions to interaction with a single web server, where the necessary session token was guaranteed to be cached on first logon.</p>
<p>In SharePoint 2013, session security tokens are stored centrally in the Distributed Cache Service&rsquo;s Logon Token cache. This cache and its tokens are thereby accessible across the farm, to all WFEs. As a result, after a user initially logs on to a SharePoint farm, they can hit any web server without the problems and penalties described in the previous paragraph. The web server uses the user&rsquo;s Windows identity or session cookie to find and use the session security token in the cache.</p>
<p>Since we&rsquo;ve introduced the logon token cache here, let&rsquo;s discuss an additional element relevant to it.</p>
<h3>The Two Parts of the Logon Token Cache</h3>
<p>The distributed logon token cache is useful, but you likely have concerns. First, if the Distributed Cache Service isn&rsquo;t running properly, the logon process and all access to the farm could be completely broken. Second, even if it&rsquo;s running properly, retrieving cached data from a remote cache service takes a bit longer than retrieving it from a local cache, and first logon is a time when this is particularly conspicuous.</p>
<p>To address these concerns, in addition to the distributed logon token cache, there&rsquo;s a complementary local logon token cache on each WFE. This is also known as the &ldquo;Weak Reference Cache&rdquo; because of the way it stores cached tokens. As long as the weak reference cache is enabled, as it is by default, logon tokens are cached in both the distributed cache and the local weak reference cache. When cached tokens are to be retrieved, first the weak reference cache is checked, and only if nothing is found there is the distributed cache checked.</p>
<p>The distributed logon token cache can be cleared with the <span style="font-family: 'courier new', courier; font-size: 10pt; background: #e5e5e5;">Clear-SPDistributedCacheItem &ndash;ContainerType DistributedLogonTokenCache</span> command. The local logon token cache can only be cleared by recycling the process where it&rsquo;s contained (e.g. the w3wp process).</p>
<p>There are two registry values which control use of the Distributed and Local (WeakRef) caches. They&rsquo;re both under HKLM:\Software\Microsoft\Shared Tools\Web Server Extensions\15.0\WSS, and are both DWORDs which default to 0 (false) if not specified. They are as follows:<br /> DisableWeakRefCacheForToken<br /> DisableDistributedCacheForToken</p>
<p>Note: I&rsquo;m not advocating changing these values under any circumstances in a production environment. Please contact Microsoft Global Business Support if you need assistance.</p>
<h3>Logon Token Cache Configuration</h3>
<p>Key properties related to the logon token caches and their default values are listed here:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; Get-SPSecurityTokenServiceConfig | Format-List *LogonToken*,*WindowsToken*<br /><br />MaxLogonTokenCacheItems&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 250<br />MaxLogonTokenOptimisticCacheItems : 100000<br />LogonTokenCacheExpirationWindow&nbsp;&nbsp; : 00:10:00<br />WindowsTokenLifetime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 10:00:00</span></p>
<p>MaxLogonTokenOptimisticCacheItems defines how many tokens are kept in the local Weak Reference cache, and MaxLogonTokenCacheItems specifies how many of these are stored as strong references instead of only weak references (details on weak references are available <a href="http://msdn.microsoft.com/en-us/library/ms404247.aspx">here</a>). LogonTokenCacheExpirationWindow specifies how close to expiration tokens are considered to already be expired. So by default, tokens are considered expired 10 minutes prior to actual expiration time. Finally, WindowsTokenLifetime is used to set the Time-To-Live in the distributed logon token cache for cached security tokens of all types (not just Windows-bootstrapped tokens).</p>
<p>With these details in mind you should be better equipped to deploy, maintain, and troubleshoot the logon token caches. Let&rsquo;s describe the usage and benefit of one other distributed cache, and then we&rsquo;ll dive into details of the cache system itself.</p>
<h2>The View State Cache</h2>
<p>ASP.NET Web Forms maintain state between requests in a session using View State. Towards the end of the page processing lifecycle, details about the page&rsquo;s state are serialized and added to the HTML to be sent to the browser as a hidden form field. When the browser posts back to the server on subsequent requests, it includes the hidden View State form field (named __VIEWSTATE). The server uses the posted back view state to rehydrate state from previously processed requests, creating the illusion of a stateful session across multiple stateless HTTP requests. ViewState has been around for a while and there are many articles available on it; <a href="http://msdn.microsoft.com/en-us/library/ms972976.aspx">here&rsquo;s</a> a good one if you&rsquo;d like a quick review. A drawback of the ASP.NET ViewState system has always been the extra data transferred to the browser and back to the server on each response and subsequent request, which can reach the tens of kilobytes.</p>
<p>SharePoint is built on ASP.NET Web Forms and as such is dependent on ViewState and its attendant drawbacks. To improve page performance, beginning in SharePoint 2013 SharePoint caches ViewState data server-side rather than transferring it back and forth to clients. In the previously linked article, pay particular attention to the section on <a href="http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic10">specifying where to persist the view state</a>. In that section, an example is presented of caching ViewState data server side by storing it in the web server&rsquo;s local file system.</p>
<p>SharePoint&rsquo;s system is similar to that presented in the article, but such a server-specific scope would lead to some of the problems discussed previously for the old logon token cache system: subsequent requests would have to be routed to the same server where ViewState was originally cached. So instead SharePoint uses the same mechanism, but persists ViewState data to the distributed ViewState cache, sending only a GUID to the browser. Compare the __VIEWSTATE hidden form field from a SharePoint 2010 page to that from a SharePoint 2013 page, and you&rsquo;ll see that only a Base64-encoded GUID remains.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/8838.ViewState_2010.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/8838.ViewState_5F00_2010.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/8838.ViewState_2010.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/8838.ViewState_5F00_2010.PNG" alt="" border="0" /></a></p>
<p>ViewState data in a SharePoint 2010 page (the large field).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/7041.ViewState_2013.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/7041.ViewState_5F00_2013.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/7041.ViewState_2013.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/7041.ViewState_5F00_2013.PNG" alt="" border="0" /></a></p>
<p>ViewState data in SharePoint 2013 (the last input field).</p>
<p>Where did all that data go? The actual ViewState data is stored in and loaded from the distributed ViewState cache, with entries for specific sessions keyed by the GUID passed back and forth from the browser. Use of this cache is governed by the SPWebService.ViewStateOnServer property, which can be accessed via these commands:</p>
<p style="background: #e5e5e5;"><span style="font-family: 'courier new', courier; font-size: 10pt;">PS:&gt; $ContentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService<br />PS:&gt; $ContentService.ViewStateOnServer</span></p>
<p>These descriptions of the distributed Logon Token Cache and distributed View State Cache will help you recognize why a distributed cache service is helpful along with some of the performance and scalability advantages it presents. Now let&rsquo;s move on to discuss the distributed cache service itself.</p>
<p>Continue with <a title="AppFabric Caching (and SharePoint) (2)" href="http://blogs.msdn.com/b/besidethepoint/archive/2013/03/27/appfabric-caching-and-sharepoint-2.aspx">AppFabric Caching (and SharePoint) (2)</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>SharePoint Apps PowerShell Helpers</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/sharepoint-apps-powershell-helpers</link>
      <pubDate>Mon, 10 Dec 2012 15:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/12/10/sharepoint-apps-powershell-helpers/</guid>
      <description><![CDATA[Setup Details Post
Download the scripts referenced in this post via the attachment at the...]]></description>
      <content:encoded><![CDATA[<p><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/12/10/sharepoint-low-trust-apps-for-on-premises-deployments.aspx">Setup Details Post</a></p>
<p><span style="font-size: medium;"><a title="Download" href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/37/62/01/LowTrustApps.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-37-62-01/LowTrustApps.zip">Download</a></span> the scripts referenced in this post via the attachment at the end.</p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Replace-SPSTSSigningCertificate.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Replace-SPSTSSigningCertificate</a></h3>
<h4>Parameters</h4>
<p>-CERPath: A location to store the newly created self-signed certificate, in case it&rsquo;s needed for other applications (e.g. AD FS). <br />-PFXPath: A location for the new self-signed certificate together with its associated private key. <br />-SPSTSCertName: The name to use for the subject and issuer name on the self-signed certificate. <br />-RootAuthorityName: The name of the root authority to be provisioned to SharePoint. <br />-CleanSTSSigningCerts: A switch parameter which, if specified, cleans old certificates with the same subject name from the local Certificates store. Useful if you are testing and creating a number of certificates and want to clean up after yourself. Be careful not to delete certificates that you still need.</p>
<h4>Dependencies</h4>
<p>SharePoint PowerShell Snapin <br />New-SelfSignedCertificate and Grant-CertificateAccess (below). These are used to generate a self-signed certificate and grant access to its private key to the SharePoint farm account.</p>
<h4>Description</h4>
<p>Creates a new self-signed certificate with subject and issuer name as specified by the SPSTSCertName parameter. This certificate is added to SharePoint as a trusted root authority, and then the signing certificate for SharePoint&rsquo;s local STS is replaced by this certificate.</p>
<p>After replacing the local STS signing certificate, I&rsquo;ve found it useful to restart the servers in the farm. Otherwise, you may encounter authentication problems while the various processes and services learn about the new certificate.</p>
<h4>Example</h4>
<p><span style="font-family: Consolas; font-size: x-small;">Replace-SPSTSSigningCertificate ` <br />&nbsp;&nbsp; -SPSTSCertName 'CN=SharePoint Security Token Service, OU=SharePoint, O=Custom, C=US' ` <br />&nbsp;&nbsp; -RootAuthorityName 'Self-Signed STS Signing Certificate' ` <br />&nbsp;&nbsp; -CerPath 'C:\temp\SPSTS.cer' ` <br />&nbsp;&nbsp; -PfxPath 'C:\temp\SPSTS.pfx' ` <br />&nbsp;&nbsp; -CleanSTSSigningCerts ` <br />&nbsp;&nbsp; -Verbose</span></p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/New-SelfSignedCertificate.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">New-SelfSignedCertificate</a></h3>
<h4>Parameters</h4>
<p>-DN: The distinguished name to be used as both the subject and issuer of the self-signed certificate. <br />-DaysValid: How many days the certificate should be valid for. Defaults to 365. <br />-PfxPath: Where to store the PFX file associated with the certificate. PFX files contain both the certificate and the associated private key. Defaults to C:\temp\SelfSignedCert.pfx. <br />-CerPath: Where to store the CER file associated with the certificate. CER files contain only the certificate, not the associated private key. Defaults to C:\temp\SelfSignedCert.cer.</p>
<h4>Dependencies</h4>
<p>None</p>
<h4>Description</h4>
<p>Creates a new self-signed certificate with the specified Distinguished Name (DN). A copy of this certificate with a reference to its private key is stored in the LocalMachine\Personal store, and a PFX and CER file are stored at the designated paths.</p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Grant-CertificateAccess.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Grant-CertificateAccess</a></h3>
<h4>Parameters</h4>
<p>-UserName: The Windows account (DOMAIN\username) which should be granted access to the private key of the certificate. <br />-Thumbprint: The thumbprint of the certificate with private key for access.</p>
<h4>Dependencies</h4>
<p>Uses ICACLS.exe to set permissions on private key file.</p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Connect-SPFarmToAAD.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Connect-SPFarmToAAD</a></h3>
<h4>Parameters</h4>
<p>-AADDomain: The fully-qualified domain name of the Azure Active Directory tenant. <br />-SharePointWebUrl: The URL of the SharePoint web application to be associated with the SharePoint principal in Azure Active Directory. <br />-O365Credentials: A PSCredential object to use for connecting to Azure Active Directory. If this isn&rsquo;t specified, you&rsquo;ll be prompted. <br />-RemoveExistingACS: Clean up ACS proxies from the SharePoint farm. <br />-RemoveExistingSTS: Clean up Trusted Security Token Service objects for ACS. <br />-RemoveExistingAADCredentials: Clean up existing credentials associated with the SharePoint principal in AAD. Useful for keeping things tidy, but be careful not to delete credentials you need.</p>
<h4>Dependencies</h4>
<p>An existing Azure Active Directory tenant. <br />MSOL PowerShell installed and configured. <br />SharePoint PowerShell snapin.</p>
<h4>Description</h4>
<p>The function starts out by declaring a few constants and gathering credentials. Metadata about the Azure Active Directory tenant is retrieved and used to associate the OnPrem SharePoint farm with the AAD realm. The Azure ACS service application proxy is configured, as well as a Trusted Security Token Service representing AAD. Next, a connection to AAD is made (using MSOL PowerShell) and the local STS signing certificate is associated with the well-known SharePoint principal. Finally, an SPN for the hostname of the URL specified in the SharePointWebUrl parameter is added to the list of known SPNs for the SharePoint principal.</p>
<h4>Example</h4>
<p><span style="font-family: Consolas; font-size: x-small;">Connect-SPFarmToAAD ` <br /></span><span style="font-family: Consolas; font-size: x-small;">&nbsp;&nbsp; -AADDomain 'joshgav1.onmicrosoft.com' ` <br /></span><span style="font-family: Consolas; font-size: x-small;">&nbsp;&nbsp; -SharePointWeb https://intranet.joshgav.com ` <br /></span><span style="font-family: Consolas; font-size: x-small;">&nbsp;&nbsp; -RemoveExistingACS ` <br /></span><span style="font-size: x-small;"><span style="font-family: Consolas;">&nbsp;&nbsp; -RemoveExistingSTS ` <br /></span><span style="font-family: Consolas;">&nbsp;&nbsp; -RemoveExistingAADCredentials</span></span></p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Add-ServicePrincipalToAAD.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Add-ServicePrincipalToAAD</a></h3>
<h4>Parameters</h4>
<p>-DisplayName: A display name for the app principal in Azure AD. <br />-RedirectUri: Endpoint URIs which tokens should be issued for. <br />-HostUri: The hostname (including port number) of the endpoint. (This could be combined with RedirectUri eventually.) <br />-ClientId: A GUID for the app principal&rsquo;s ID. Autogenerated if not specified. <br />-ClientSecret: A symmetric key secret for use with the client ID. Autogenerated if not specified. <br />-O365Credentials: Credentials for the AAD tenant. <br />-RemoveExistingWithSameDisplayName: Clean up existing service principals with the same display name. Careful not remove ones still in use.</p>
<h4>Dependencies</h4>
<p>An existing Azure Active Directory tenant. <br />MSOL PowerShell installed and configured.</p>
<h4>Description</h4>
<p>Begins with some setup: collect credentials to connect to AAD, create a client secret if one hasn&rsquo;t been specified, and create an SPN to represent the location of the remote-hosted Web Application. Then the real work of connecting to AAD and creating a new service principal. The ClientSecret has to be associated with the service principal in several ways. Finally, the ClientID and ClientSecret that were used are output for further use.</p>
<h4>Example</h4>
<p><span style="font-family: Consolas; font-size: x-small;">Add-ServicePrincipalToAAD ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-DisplayName 'OnPremApp1' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RedirectUri 'https://localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-HostUri 'localhost:44300' <br />&nbsp;&nbsp; </span><span style="font-size: x-small;"><span style="font-family: Consolas;">-O365Credentials $Credential ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas;">-RemoveExistingWithSameDisplayName</span></span></p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Register-SPAppPrincipalEx.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Register-SPAppPrincipalEx</a></h3>
<h4>Parameters</h4>
<p>-Web: A SharePoint web. This helps set the context for the operation; the app principal is available for use across the entire SharePoint tenancy. <br />-ClientId: The client ID (a GUID) for this app principal. <br />-ClientSecret: The Base64-encoded secret for this app principal. <br />-DisplayName: Display name for the app principal. <br />-HostUri: The hostname (including port) where the remote-hosted app is published. <br />-RedirectUri: The HTTP/S endpoint where requests for apps associated with this app principal will be redirected.</p>
<h4>Dependencies</h4>
<p>SharePoint PowerShell snapin.</p>
<h4>Description</h4>
<p>Using the specified parameters, creates an AppPrincipal in SharePoint to be associated with apps. Note the similarity between this function and the one for adding a service principal to AAD. Eventually, app principal registrations in SharePoint will automatically create a parallel registration in AAD. In the meantime, specify the same values for each function.</p>
<h4>Example</h4>
<p><span style="font-family: Consolas; font-size: x-small;">$AppPrincipal = Register-SPAppPrincipalEx ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-Web https://intranet.joshgav.com ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-ClientId $ClientInfo.ClientId ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-ClientSecret $ClientInfo.ClientSecret ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-HostUri 'localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-size: x-small;"><span style="font-family: Consolas;">-RedirectUri 'https://localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas;">-DisplayName $ClientInfo.ClientDisplayName</span></span></p>
<h3><a href="https://joshgav.blob.core.windows.net/powershell/Configure-SPFarmAppIsolation.ps1?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">Configure-SPFarmAppIsolation</a></h3>
<h4>Parameters</h4>
<p>-AppPrefix: The prefix placed before every AppWeb URL. <br />-AppDomain: The domain which follows the AppWeb prefix. <br />-ADDomain: The AD Domain in which the wildcard DNS entry for the AppDomain will be placed. <br />-CanonicalName: The server to which the CNAME record for the wildcard DNS entry should point. <br />-AddWildcardDNSEntry: Specify $false to not add the DNS entry. Defaults to true; use -AddWildcardDNDEntry:$false to specify false.</p>
<h4>Dependencies</h4>
<p>SharePoint PowerShell snapin</p>
<h4>Description</h4>
<p>Sets up App Isolation for SharePoint.</p>
<h4>Example</h4>
<p><span style="font-family: Consolas; font-size: x-small;">Configure-SPFarmAppIsolation ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-AppPrefix 'apps' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-AppDomain 'apps.intranet.joshgav.com' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-ADDomain 'gavant.local' ` <br />&nbsp;&nbsp; </span><span style="font-size: x-small;"><span style="font-family: Consolas;">-CanonicalName 'intranet.joshgav.com' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas;">-AddWildcardDNSEntry</span></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/37/62/01/LowTrustApps.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-37-62-01/LowTrustApps.zip">LowTrustApps.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SharePoint Low-Trust Apps for On-Premises Deployments</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/sharepoint-low-trust-apps-for-on-premises-deployments</link>
      <pubDate>Mon, 10 Dec 2012 15:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/12/10/sharepoint-low-trust-apps-for-on-premises-deployments/</guid>
      <description><![CDATA[PowerShell Functions and Scripts Post
Note: I&rsquo;ve been wanting to share the details on setting...]]></description>
      <content:encoded><![CDATA[<p><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/12/10/sharepoint-apps-powershell-helpers.aspx">PowerShell Functions and Scripts Post</a></p>
<p>Note: I&rsquo;ve been wanting to share the details on setting up an OnPrem SharePoint environment to support low-trust apps for a while now. I had some help from the Product Group to get things working, and there were several catches and &lsquo;Aha!&rsquo; moments involved which many of you are I&rsquo;m sure stumbling over. So I dug in today and hammered out this post and the <a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/12/10/sharepoint-apps-powershell-helpers.aspx" target="_blank">associated post</a> of PowerShell helper functions to get this info out there. Let me know if (and when!) you find details that need clarification or might need correction. Enjoy!</p>
<h3>A quick summary of SharePoint apps</h3>
<p>SharePoint apps can be hosted inside SharePoint or outside of it. Apps hosted outside of SharePoint can be manually provisioned to an IIS server, an Apache server, an Azure Compute Services role, or any other host; or can be automatically provisioned and hosted in Azure Web Sites. Externally-hosted apps can call into SharePoint to request data on behalf of the user using the App Authentication model, an implementation of OAuth. Of the several OAuth profiles available, SharePoint apps implement and extend two of them under the names &ldquo;High-Trust&rdquo; and &ldquo;Low-Trust.&rdquo; In this post, we&rsquo;ll discuss the protocol flow for SharePoint low-trust apps and how to configure an On-Prem SharePoint farm to support it.</p>
<h3>A brief history of OAuth</h3>
<p>OAuth version 1 was prepared by some of the biggest names of Web 2.0 - Twitter, Google, Facebook, Flickr. It provides a simple means for users to delegate limited authorization to their data to applications and services without sharing master credentials (e.g. username and password). For example, by using OAuth Facebook doesn&rsquo;t need to ask you to share your Google password to get your Google contacts; instead you delegate to Facebook specific authorization to read your Google contacts list. In the canonical example (from the RFC), you can grant a photo printing service authorization to read your photos from a photo storage service without sharing your password with the printing service or granting that service read/write privileges to your photos and other account data at the photo storage service provider.</p>
<p>OAuth version 2 has been under discussion for several years now and <a href="http://datatracker.ietf.org/doc/rfc6749/">RFC 6749</a> is the first of <a href="http://datatracker.ietf.org/wg/oauth/">several RFCs</a> documenting it. Significant (and controversial) additions to OAuth 2 include the <a href="http://datatracker.ietf.org/doc/draft-ietf-oauth-json-web-token/">JavaScript Web Token</a> (JWT, pronounced &lsquo;jot&rsquo;) profile and the <a href="http://datatracker.ietf.org/doc/draft-ietf-oauth-assertions/">OAuth Assertion Framework</a>, which together have made it easier to use OAuth for authentication as well as delegated authorization. Microsoft&rsquo;s implementations of OAuth make heavy use of JWTs, and you&rsquo;ll find the <a href="http://datatracker.ietf.org/doc/draft-ietf-oauth-jwt-bearer/">JWT Bearer Token profile</a> to be the foundation for Microsoft&rsquo;s High-Trust, Server-to-Server authentication schemes. For low-trust authentication, SharePoint uses a version of the classic authorization code flow discussed in the previous paragraph.</p>
<h3>OAuth in SharePoint low-trust apps</h3>
<p>SharePoint low-trust apps rely on the OAuth authorization code flow (&ldquo;grant type&rdquo;) to delegate limited rights to apps to act as users. For this to work, both SharePoint and the Client application (the SharePoint app) must trust and communicate with an Authentication Provider; SharePoint relies on Azure Active Directory. Azure AD, in turn, must be aware of SharePoint and the Client app in order to grant them the necessary codes and tokens to work together.</p>
<p>Let&rsquo;s orient ourselves by presenting the overall protocol flow:</p>
<p><a href="https://joshgav.blob.core.windows.net/images/OAuth-SharePoint2013.png"><img style="display: inline; background-image: none;" title="SharePoint 2013 OAuth" src="https://joshgav.blob.core.windows.net/images/OAuth-SharePoint2013.png" alt="SharePoint 2013 OAuth" width="454" height="590" border="0" /></a></p>
<p>In this picture, the &lsquo;S&rsquo; icon represents SharePoint and the globe represents an externally-hosted SharePoint app. The floating blue window represents Azure Active Directory, as indicated. In <strong>step 1</strong>, a user requests a page or an app directly from SharePoint. The app could be hosted directly within a SharePoint page in an IFrame, or might be on its own page. In either case, SharePoint will need to send the user&rsquo;s browser to the external host to retrieve the app page, either via the location tag of the IFrame element or a 302 Redirect HTTP status; it will do so in step 3. First, though, SharePoint gets an OAuth authorization code to share with the app; the app will use this code to ultimately communicate back with SharePoint acting as the user. In <strong>step 2</strong>, SharePoint asks Azure Active Directory Access Control Service for an authorization code for the app. Now, in <strong>step 3</strong>, SharePoint redirects the user&rsquo;s browser to the app, including the authz code with the redirected request (as the SPAppToken form parameter).</p>
<p>The app doesn&rsquo;t use the authorization code directly to authenticate to SharePoint. Instead, in <strong>step 4</strong> it calls Azure AD ACS and exchanges the authorization code it received from SharePoint for a proper Access Token. In <strong>step 5</strong> the app uses this access token to authenticate to and access data from SharePoint, and finally in <strong>step 6</strong> it uses this data to present a page to the user.</p>
<h3>Setup SharePoint for low-trust apps</h3>
<p>There&rsquo;s lots to say about the various steps in this flow, but our focus here will be on setting up an On-Premises SharePoint 2013 farm to participate in it via a connection to Azure Active Directory. Most of this post will focus on enabling step 2 above - the connection between SharePoint and Azure Active Directory. The three steps you&rsquo;ll need to follow to setup a SharePoint farm for low-trust apps are as follows:</p>
<ol>
<li>General SharePoint setup for apps (e.g. App Management Service Application, app isolation).</li>
<li>Connect SharePoint to Azure Active Directory.</li>
<li>Create an App Principal in AAD and SharePoint.</li>
</ol>
<p>Step 1 is already <a href="http://technet.microsoft.com/en-us/library/fp161236">well-documented on TechNet</a> and other Web sites, so we&rsquo;ll start at step 2.</p>
<h3>Connect SharePoint to Azure Active Directory</h3>
<p>If you haven&rsquo;t yet, follow the steps in <a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/10/23/getting-started-with-azure-active-directory.aspx">my previous post</a> to get the Azure Active Directory module for PowerShell set up. You&rsquo;ll need an AAD tenant and AAD/MSOL PowerShell for the next steps, and you&rsquo;ll follow the discussion better after you&rsquo;ve experimented a bit with AAD.</p>
<p>To completely configure a connection between your OnPrem SharePoint farm and Azure AD, you&rsquo;ll need to complete the following steps:</p>
<ol>
<li>Replace the local STS signing certificate with one Azure AD can trust. I use a self-signed certificate, though a certificate from a trusted global authority should also work.</li>
<li>Associate this certificate with the SharePoint principal in Azure Active Directory.</li>
<li>Create an SPN for the OnPrem SharePoint farm and add it to the SharePoint principal in Azure Active Directory.</li>
<li>Configure the authentication realm for the local SharePoint farm to match the AAD realm.</li>
<li>Create an Azure Access Control Service application proxy in SharePoint.</li>
<li>Create a Trusted Security Token Service for Azure ACS in SharePoint.</li>
</ol>
<p>Remember that in step 2 above SharePoint calls in to AAD to request an authorization code, which requires authentication. The SharePoint username for this authentication is a well-known GUID representing SharePoint in Azure AD and O365 (00000003-0000-0ff1-ce00-000000000000). The credential used is an X.509 certificate, specifically SharePoint&rsquo;s local STS signing certificate. Worth stating again: <em>the same certificate used by SharePoint&rsquo;s local STS to sign security tokens is used by SharePoint to authenticate to Azure Active Directory</em>. That&rsquo;s why the first step above is to replace the local signing certificate with one that can be used for authentication to AAD</p>
<p>I&rsquo;ve created PowerShell functions which take care of the above steps and which you can review for the technical nitty-gritty; they&rsquo;re named Replace-SPSTSSigningCertificate and Connect-SPFarmToAAD. You can access them individually at this post&rsquo;s <a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/12/10/sharepoint-apps-powershell-helpers.aspx" target="_blank">sister post</a>, or download the whole package of scripts related to this post <a href="https://joshgav.blob.core.windows.net/powershell/LowTrustApps.zip?sv=2012-02-12&amp;sr=c&amp;si=BlogReaders&amp;sig=IQJUOzT1KTeyRLWZMR8%2BSenPkas2f8dDpQHZQeDRvxE%3D">here</a>. For further details, refer to the sister post and to the scripts themselves.</p>
<p>If you&rsquo;ve saved all the files to the same directory, you can navigate there and use the following commands to set up your connection, replacing the AADDomain name and SharePoint Web URL appropriately. In the zip file, a similar script is available named &lsquo;_ConnectSharePointToAAD.ps1&rsquo;.</p>
<p><span style="font-family: Consolas; font-size: x-small;">$FolderPath = if ($psISE) {Split-Path -Path $psISE.CurrentFile.FullPath -Parent} elseif ($PSScriptRoot) {$PSScriptRoot} else {"."} <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'New-SelfSignedCertificate.ps1') <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'Grant-CertificateAccess.ps1') <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'Replace-SPSTSSigningCertificate.ps1') <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'Connect-SPFarmToAAD.ps1')</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">Add-PSSnapin Microsoft.SharePoint.PowerShell <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name MSOnline</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">Replace-SPSTSSigningCertificate ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-SPSTSCertName 'CN=SharePoint Security Token Service, OU=SharePoint, O=Custom, C=US' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RootAuthorityName 'Self-Signed STS Signing Certificate' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-CerPath 'C:\temp\SPSTS.cer' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-PfxPath 'C:\temp\SPSTS.pfx' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-CleanSTSSigningCerts ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-Verbose</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">Write-Warning 'The STS Signing Certificate has been replaced. It is recommended that you restart your system before continuing.'</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">Connect-SPFarmToAAD ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-AADDomain 'joshgav1.onmicrosoft.com' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-SharePointWebUrl https://intranet.joshgav.com ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RemoveExistingACS ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RemoveExistingSTS ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RemoveExistingAADCredentials ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-Verbose</span></p>
<h3>Create App Principals</h3>
<p>We&rsquo;ve connected SharePoint to AAD, but to actually utilize this connection, we need to create AppPrincipals in Azure Active Directory and SharePoint. These AppPrincipals represent the remote-hosted Web Applications which will connect to SharePoint acting as users. Azure AD needs to be aware of these principals to be able to issue authorization codes for them (step 2) and access tokens to them (step 4). SharePoint needs to be aware of them to allow them access on behalf of users (step 5).</p>
<p>As things currently stand, you must create principals separately in SharePoint and in AAD. Work is underway to allow SharePoint to create a service principal in AAD automatically. In the meantime, though, we&rsquo;ll use two separate functions to create an AppPrincipal in AAD and SharePoint. Again, refer to the <a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/12/10/sharepoint-apps-powershell-helpers.aspx" target="_blank">sister post</a> for details on these two functions, Add-ServicePrincipalToAAD and Register-SPAppPrincipalEx. Note that you&rsquo;ll need the ClientID and Client Secret you use here when you create your SharePoint app, so don&rsquo;t lose them!</p>
<p>An example, included in the zip as &lsquo;_NewAppPrincipal.ps1,&rsquo; follows:</p>
<p><span style="font-family: Consolas; font-size: x-small;">$FolderPath = if ($psISE) {Split-Path -Path $psISE.CurrentFile.FullPath -Parent} elseif ($PSScriptRoot) {$PSScriptRoot} else {"."} <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'Register-SPAppPrincipalEx.ps1') <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module -Name ('{0}\{1}' -f $FolderPath,'Add-ServicePrincipalToAAD.ps1')</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">$Credential = Get-Credential -Message 'O365 Credential'</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">Add-PSSnapin Microsoft.SharePoint.PowerShell <br /></span><span style="font-family: Consolas; font-size: x-small;">Import-Module MSOnline</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">$ClientInfo = Add-ServicePrincipalToAAD ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-DisplayName 'OnPremApp1' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RedirectUri 'https://localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-HostUri 'localhost:44300' ` <br />&nbsp;&nbsp; -</span><span style="font-family: Consolas; font-size: x-small;">O365Credentials $Credential ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RemoveExistingWithSameDisplayName</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">$AppPrincipal = Register-SPAppPrincipalEx ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-Web https://intranet.joshgav.com ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-ClientId $ClientInfo.ClientId ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-ClientSecret $ClientInfo.ClientSecret ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-HostUri 'localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-RedirectUri 'https://localhost:44300' ` <br />&nbsp;&nbsp; </span><span style="font-family: Consolas; font-size: x-small;">-DisplayName $ClientInfo.ClientDisplayName</span></p>
<p><span style="font-family: Consolas; font-size: x-small;">$ClientInfo</span></p>
<h3>Create a Remote-Hosted App</h3>
<p>At this point, your environment is set. You can create a provider-hosted app in Visual Studio and specify the ClientID and ClientSecret created here in the web.config file. The MSDN samples have a <a href="http://code.msdn.microsoft.com/SharePoint-2013-Hello-0fd15fbf">Hello World app</a> to get you started. Don&rsquo;t forget to change the ClientID and ClientSecret in web.config.</p>]]></content:encoded>
    </item>
    <item>
      <title>Getting Started with Azure Active Directory</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/getting-started-with-azure-active-directory</link>
      <pubDate>Tue, 23 Oct 2012 08:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/10/23/getting-started-with-azure-active-directory/</guid>
      <description><![CDATA[So you&rsquo;ve heard the rumblings about Azure Active Directory and would like to find...]]></description>
      <content:encoded><![CDATA[<p class="Publishwithline"><span style="font-size: small;"><span style="font-family: Calibri;">So you&rsquo;ve heard the rumblings about Azure Active Directory and would like to find out&nbsp;more on&nbsp;what it&rsquo;s all about. Let&rsquo;s get you set up with some of the key pieces you&rsquo;ll need and introduce a few concepts at the same time.</span></span></p>
<p class="Publishwithline"><em><span style="font-size: medium;"><span style="font-family: Calibri;">Updated 2/28/2013 to account for the updated AAD PowerShell module (<a href="https://aka.ms/aadposh" target="_blank">https://aka.ms/aadposh</a>).</span></span></em></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">Sign up for Azure Active Directory</span></span></h1>
<p><span style="font-family: Calibri; font-size: small;">Azure Active Directory provides the directory and access control service for Office 365, so if you have an O365 subscription of any sort you already have a corresponding AAD tenancy. If you don&rsquo;t have one or prefer a different tenancy for testing, sign up for an AAD account </span><a href="https://activedirectory.windowsazure.com/Signup/SignupCompanyAndTenant.aspx?ru=https://activedirectory.windowsazure.com/default.aspx&amp;ali=1"><span style="color: #0563c1; font-family: Calibri; font-size: small;">here</span></a><span style="font-family: Calibri; font-size: small;">, or a new O365 Enterprise Preview account </span><a href="https://portal.microsoftonline.com/Signup/MainSignup15.aspx?OfferId=D214930B-46C2-4FD2-B7F9-EC134993F34A&amp;dl=ENTERPRISEPACK_B_PILOT&amp;pc=O365-Preview-2012&amp;ali=1"><span style="color: #0563c1; font-family: Calibri; font-size: small;">here</span></a><span style="font-size: small;"><span style="font-family: Calibri;">.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">You can access a Web UI for user management at </span><a href="https://activedirectory.windowsazure.com"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://activedirectory.windowsazure.com</span></a><span style="font-size: small;"><span style="font-family: Calibri;">. Right now the only significant task you can accomplish via the UI is some user management. Managing service principals and identity and authentication configuration requires PowerShell.</span></span></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">Install and Prepare MSOL PowerShell</span></span></h1>
<p><span style="font-family: Calibri; font-size: small;">Azure Active Directory PowerShell was formerly known as Microsoft Online (MSOL) PowerShell, and most cmdlets still use the MSOL prefix. The module requires the Microsoft Online Sign-In Assistant (MSO SIA). You can download the Sign-In Assistant </span><span style="color: #0563c1; font-family: Calibri; font-size: small;"><a title="here" href="http://go.microsoft.com/fwlink/p/?linkid=236300">here</a></span><span style="font-family: Calibri; font-size: small;"> and the 64-bit PowerShell module </span><span style="color: #0563c1; font-family: Calibri; font-size: small;"><a title="here" href="http://go.microsoft.com/fwlink/p/?linkid=236297">here</a></span><span style="font-family: Calibri; font-size: small;"> (reference to 32-bit and 64-bit editions of the SIA and AAD module&nbsp;are </span><span style="color: #0563c1; font-family: Calibri; font-size: small;"><a title="here" href="http://technet.microsoft.com/en-us/library/jj151805.aspx#BKMK_install">here</a></span><span style="font-size: small;"><span style="font-family: Calibri;">).</span></span></p>
<p><em><span style="color: #888888; font-size: medium;"><span style="font-family: Calibri;">Note (Feb 28, 2013): The following workaround is no longer necessary with the release of the AAD PowerShell module. You can still delete the MSOnlineExtended folder if you want, but the CmdletsToExport line is now correct by default.</span></span></em></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Calibri;">Before you get started with your new cmdlets, you&rsquo;ll need to work around some problems. AAD PowerShell installs two modules into the PowerShell module directory at C:\windows\system32\windowspowershell\v1.0\modules. These are the MSOnline and MSOnlineExtended modules. At this point, both modules include the exact same DLL; as a result, PowerShell can&rsquo;t load both modules in the same session at once. The best way to deal with this is as follows:</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Calibri;">Throw out the entire MSOnlineExtended module. If it makes you nervous, just move it somewhere else. But I promise you won&rsquo;t have any issues if you completely delete it. (Note: This is current as of Oct 23, 2012).</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Calibri;">Next, open up the MSOnline module folder (in the $pshome\modules directory), and open MSOnline.psd1 somewhere you can edit it. One option is to run this command in the PowerShell ISE (running as Administrator):</span></span></p>
<p class="Code" style="padding-left: 30px;"><span style="color: #000080; font-family: courier new,courier; font-size: small; background-color: #ffffff;"><span><span>PS C:\&gt; psedit $pshome\modules\msonline\msonline.psd1</span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Calibri;">Find the line for CmdletsToExport and change it to this:</span></span></p>
<p class="Code" style="padding-left: 30px;"><span style="color: #000080; font-family: courier new,courier; font-size: small;"><span><span>PS C:\&gt; CmdletsToExport = &lsquo;*&rsquo;</span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Calibri;">What you&rsquo;re doing here is specifying that all available cmdlets in MSOL PowerShell DLLs should&nbsp;be exported into your PowerShell sessions via the MSOnline module.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Once you&rsquo;ve done this, re-open PowerShell and run:</span></span></p>
<p class="Code"><span style="color: #000080; font-family: courier new,courier; font-size: small;"><span><span>PS C:\&gt; Get-Command -Module MSOnline</span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">If all is well, you&rsquo;ll see a list of all the Azure AD cmdlets. Look for the MsolServicePrincipal ones in particular.</span></span></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">Connect to AAD</span></span></h1>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Now we&rsquo;ll get acquainted with the service principals which initially populate your directory. First, you&rsquo;ll need to establish the context for your session via the Connect-MsolService cmdlet. Just enter the cmdlet and put in your administrative credentials for your O365/AAD tenancy. In the background, a persistent connection is set up and cached for use with all the MSOL cmdlets you use in your session.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">Curious what&rsquo;s happening behind the scenes here? Open up a Web Proxy Debugger (e.g. </span><a href="http://www.fiddler2.com/fiddler2/"><span style="color: #0563c1; font-family: Calibri; font-size: small;">Fiddler2</span></a><span style="font-family: Calibri; font-size: small;">), make sure you have set it to </span><a href="http://www.fiddler2.com/fiddler/help/httpsdecryption.asp"><span style="color: #0563c1; font-family: Calibri; font-size: small;">decrypt HTTPS connections</span></a><span style="font-size: small;"><span style="font-family: Calibri;">, and then run the Connect-MsolService cmdlet. You&rsquo;ll see that a special SOAP request is sent to the BEC Web Service. BEC, or Business Online Services Engineering Core, is Microsoft&rsquo;s name for the gateway to Azure AD. You&rsquo;ll occasionally see it turn up in contexts where a connection to AAD is needed, such as in SharePoint 2013 PowerShell (New-SPBecWebServiceApplicationProxy).</span></span></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">Service Principals and Domains</span></span></h1>
<p><span style="font-size: small;"><span style="font-family: Calibri;">The first cmdlet to run once you&rsquo;re all connected is Get-MsolServicePrincipal. If you have O365 set up, you&rsquo;ll see principals for each of the online services, such as Exchange, SharePoint, and Lync. Here&rsquo;s a list of the principals currently in my AAD domain.</span></span></p>
<p class="CodeCxSpFirst"><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PS C:\&gt; Get-MsolServicePrincipal | ft DisplayName, AppPrincipalId -AutoSize</span></span></span></p>
<p class="CodeCxSpMiddle"><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>DisplayName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AppPrincipalId<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>-----------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --------------<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Lync&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000004-0000-0ff1-ce00-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Office365Portal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000006-0000-0ff1-ce00-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.SharePoint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000003-0000-0ff1-ce00-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Azure.Workflow&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000005-0000-0000-c000-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Azure.AnalysisServices&nbsp;&nbsp;&nbsp; 00000009-0000-0000-c000-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Exchange&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000002-0000-0ff1-ce00-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.ExchangeOnlineProtection&nbsp; 00000007-0000-0ff1-ce00-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>Microsoft.Azure.ActiveDirectory&nbsp;&nbsp;&nbsp;&nbsp; 00000002-0000-0000-c000-000000000000<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>&ldquo;Napa&rdquo; Office 365 Development Tools 48717084-a59c-4306-9dc4-3f618dbecdf9<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>OnPremApp1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 52f3de70-2d75-4187-9c49-138d86e54244<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>rp.joshgav.com&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 66b3011d-892c-4cbe-a844-61d87ecdf8f8 </span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Notice the last 3? Those are principals that I&rsquo;ve added as relying OAuth and WS-Trust parties. The last one is a Relying Party Web Application of mine. I created the principal in AAD and then ran the Identity and Access tool in Visual Studio to federate with Azure AD for single-sign on. More on that another time.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">If Service Principals are approximately equivalent to Relying Parties (WS-Federation) and Service Providers (SAML), then Domains are Identity Providers (WS-Fed) and Authentication Authorities (SAML). Run Get-MsolDomain to see all of your AAD domains. If you&rsquo;ve </span><a href="http://technet.microsoft.com/en-us/library/hh689731.aspx"><span style="color: #0563c1; font-family: Calibri; font-size: small;">federated your O365 directory with an On-Prem ADFS STS</span></a><span style="font-size: small;"><span style="font-family: Calibri;">, you&rsquo;ll see it listed as a Federated domain here. I&rsquo;ve federated &lsquo;gavant.org.&rsquo;</span></span></p>
<p class="CodeCxSpFirst"><span style="color: #000080; font-family: courier new,courier; font-size: small;"><span><span>PS C:\&gt; Get-MsolDomain | ft -AutoSize<br /></span></span></span></p>
<p class="CodeCxSpMiddle"><span style="color: #000080; font-size: small;"><span style="font-family: courier new,courier;"><span><span>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Status&nbsp;&nbsp; Authentication<br /></span></span></span><span style="font-family: courier new,courier;"><span><span>----&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------&nbsp;&nbsp; --------------<br /></span></span></span><span style="font-family: courier new,courier;"><span><span>gavant.org&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Verified Federated<br /></span></span></span><span style="font-family: courier new,courier;"><span><span>joshgav1.onmicrosoft.com&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Verified Managed</span></span></span><span style="font-family: courier new,courier;">&nbsp;</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">If you have a federated domain, run Get-MsolDomainFederationSettings to see how AAD routes authentication requests back to your OnPrem ADFS instance. Here&rsquo;s my configuration:</span></span></p>
<p class="CodeCxSpFirst"><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PS C:\&gt; Get-MsolDomainFederationSettings -DomainName gavant.org</span></span></span></p>
<p class="CodeCxSpMiddle"><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>ActiveLogOnUri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : https://fs.joshgav.com/adfs/services/trust/2005/usernamemixed<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>FederationBrandName&nbsp;&nbsp;&nbsp; : JoshGav ADFS<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>IssuerUri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : https://fs.joshgav.com/adfs/services/trust/<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>LogOffUri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : https://fs.joshgav.com/adfs/ls/<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>MetadataExchangeUri&nbsp;&nbsp;&nbsp; : https://fs.joshgav.com/adfs/services/trust/mex<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>NextSigningCertificate : <br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PassiveLogOnUri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : https://fs.joshgav.com/adfs/ls/<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>SigningCertificate&nbsp;&nbsp;&nbsp;&nbsp; : MIIC2DCCAcCgAwIBAgIQf2RJ+RmnbqhMANBCDJz6ojANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDEx1BREZTIFNpZ25pbmcgLSBmcy5qb3NoZ2F2LmNvbTAeFw0xMjEwMDExMzI4MjhaFw0xMzEwMDExMzI4MjhaMCgxJjAkBgNVBAMTHUFERlMgU2lnbmluZyAtIGZzLmpvc2hnYXYuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZ6zVYGdqKk04lCxbqjZjd+Nhu7GlFhnz1RBWKNevxWPP9bsMR5B/...</span></span></span></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">More Metadata</span></span></h1>
<p><span style="font-size: small;"><span style="font-family: Calibri;">We&rsquo;ve briefly seen Service Principals and Identity Providers. What we&rsquo;re missing is information about the AAD STS itself. The best way to see more about this is to retrieve the Federation Metadata document and the JSON Metadata document for your AAD realm. Assuming {0} to be a placeholder for your AAD domain name or realm ID, the following URLs will get you the information you need.</span></span></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="157">
<p><span style="font-size: small;"><span style="font-family: Calibri;">WS-Federation</span></span></p>
</td>
<td valign="top" width="622">
<p><span style="font-size: small;"><span style="font-family: Calibri;">https://accounts.accesscontrol.windows.net/{0}/FederationMetadata/2007-06/FederationMetadata.xml</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="157">
<p><span style="font-size: small;"><span style="font-family: Calibri;">JSON</span></span></p>
</td>
<td valign="top" width="622">
<p><span style="font-size: small;"><span style="font-family: Calibri;">https://accounts.accesscontrol.windows.net/{0}/metadata/json/1</span></span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;"><span style="font-family: Calibri;">I have no idea what standard the JSON information adheres to, but Microsoft uses it here and in other products.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">For example, you can retrieve the metadata for my AAD tenant at </span><span style="color: #0563c1; font-family: Calibri; font-size: small;"><a href="https://accounts.accesscontrol.windows.net/gavant.org/FederationMetadata/2007-06/FederationMetadata.xml">https://accounts.accesscontrol.windows.net/joshgav1.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml</a></span><span style="font-size: small;"><span style="font-family: Calibri;">. Go ahead, click it.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">Personally, I prefer to use PowerShell:</span></span></p>
<p class="CodeCxSpFirst"><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PS:&gt; $AADDomain = &lsquo;joshgav1.onmicrosoft.com&rsquo;<br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PS:&gt; [xml] $Output = (<br />&nbsp;&nbsp;&nbsp; Invoke-RestMethod `<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>-Uri (&lsquo;https://accounts.accesscontrol.windows.net/{0}/FederationMetadata/2007-06/FederationMetadata.xml&rsquo; -f $AADDomain)).SubString(1)<br /><br /></span></span></span><span style="color: #003366; font-family: courier new,courier; font-size: small;"><span><span>PS:&gt; Invoke-RestMethod -Uri (&lsquo;https://accounts.accesscontrol.windows.net/{0}/metadata/json/1&rsquo; -f $AADDomain)</span></span></span></p>
<p><span style="font-size: small;"><span style="font-family: Calibri;">The metadata document returned in the first command has an extra character at the beginning, which is why we have the extra SubString(1) method tacked on. Invoke-RestMethod is a very helpful PowerShell cmdlet which converts JSON objects into PowerShell objects automatically, as you can in the last command above.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;">The metadata you receive is all about the Azure AD Access Control Service. You&rsquo;ll notice it has a Principal ID of 00000001-0000-0000-c000-000000000000 (which was missing in the list above). The perceptive amongst you will notice that its main endpoint is </span><a href="https://accounts.accesscontrol.windows.net/RealmID"><span style="color: #0563c1; font-family: Calibri; font-size: small;">https://accounts.accesscontrol.windows.net/RealmID</span></a><span style="font-size: small;"><span style="font-family: Calibri;">, which may remind you of the ACS 2.0 domains. In ACS 2.0, domains are named <span style="text-decoration: underline;"><span style="color: #0563c1; text-decoration: underline;">https://&lt;namespace&gt;.accesscontrol.windows.net</span></span>. In AAD ACS, the root domain accounts.accesscontrol.windows.net is shared by all tenants.</span></span></p>
<h1><span style="color: #2e74b5;"><span style="font-family: Calibri;">Summary</span></span></h1>
<p><span style="font-size: small;"><span style="font-family: Calibri;">In this post we&rsquo;ve gotten you set up with an AAD account, installed and fixed MSOL PowerShell, and taken a brief tour of AAD service principals, domains, and the AAD Access Control Service itself. Use this knowledge to begin composing and federating domains and identity providers with your AAD tenancy.</span></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Request ADFS Security Token with PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/request-adfs-security-token-with-powershell</link>
      <pubDate>Wed, 17 Oct 2012 05:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/10/17/request-adfs-security-token-with-powershell/</guid>
      <description><![CDATA[In the course of my work I often have need to investigate end-to-end protocol flows. For...]]></description>
      <content:encoded><![CDATA[<p><meta name="Generator" content="Microsoft Word 15 (filtered)" /></p>
<div class="WordSection1">
<p class="Publishwithline"><span style="font-family: tahoma, arial, helvetica, sans-serif;">In the course of my work I often have need to investigate end-to-end protocol flows. For example, I want to see an RST being generated, I want to see HTTP 302 or 200 responses coming back from a server, and I want to see what my SOAP messages actually look like on the wire. Unfortunately for me and fortunately for end users, most applications strive to hide this detail as much as possible. To help myself and others in our work, I&rsquo;ve written some nifty PowerShell functions to reveal the details that others have hidden.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Here I&rsquo;ll share a function designed to request a security token from an ADFS server. It relies on .NET 4.5 and can be run from any system with Web access to the ADFS endpoints. It runs against the following two ADFS endpoints, so you&rsquo;ll need to make sure they&rsquo;re enabled on your ADFS server:</span></p>
<ul>
<li><span style="text-indent: -0.25in; font-family: tahoma, arial, helvetica, sans-serif;">/adfs/services/trust/windowsmixed -&nbsp;<span>WS-Trust 1.3, Windows, TransportWithMessageCredential (Mixed)</span></span></li>
<li><span style="text-indent: -0.25in; font-family: tahoma, arial, helvetica, sans-serif;">/adfs/services/trust/usernamemixed -&nbsp;<span>WS-Trust 1.3, Password, TransportWithMessageCredential (Mixed)</span></span></li>
</ul>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">You can download the function from the TechNet Script Gallery <a href="http://gallery.technet.microsoft.com/scriptcenter/Invoke-ADFSSecurityTokenReq-09e9c90c" target="_blank">here</a>. In this post, we&rsquo;ll step through how it works.<a name="_GoBack"></a></span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">The parameters for the function are:</span></p>
<ul>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">ClientCredentialType</b><span style="text-indent: -0.25in;">: Will authentication be done via Windows authentication (SSPI negotiation) or a UserName/Password token. This determines which address in ADFS will be used and which binding will be configured.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">ADFSBaseUri</b><span style="text-indent: -0.25in;">: The root URI of your ADFS application. For me, this is </span>https://fs.joshgav.com<span style="text-indent: -0.25in;">, and yours is probably similar.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">AppliesTo</b><span style="text-indent: -0.25in;">: The Relying Party realm the token is to be issued for. You&rsquo;ll need to have previously configured this RP in ADFS.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">Username, Password, Domain</b><span style="text-indent: -0.25in;">: Self-explanatory I think. I&rsquo;m not sure if you need the domain or not, and will update this when I confirm that.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">SAMLVersion</b><span style="text-indent: -0.25in;"> (1 or 2): ADFS will give you SAML 1.1 assertions by default, but you can request SAML 2. This parameter helps you specify which you want.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">OutputType</b><span style="text-indent: -0.25in;"> (Token or RSTR): Choose if you want back a .NET SecurityToken object or a RequestSecurityTokenResponse object. Both have their uses.</span></span></li>
<li><span style="font-family: tahoma, arial, helvetica, sans-serif;"><b style="text-indent: -0.25in;">IgnoreCertificateErrors</b><span style="text-indent: -0.25in;">: Do you know how expensive SSL certficates are? Save yourself some cash and set up your own Certificate Authority for testing. Specify this switch to ignore certificate problems during the request.</span></span></li>
</ul>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">The first lines in the function are:</span></p>
<p class="MsoNormal"></p>
<br /> <span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$ADFSTrustPath</span> <span style="color: #a9a9a9;">=</span> 'adfs/services/trust/13'</span>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$SecurityMode</span> <span style="color: #a9a9a9;">=</span> 'TransportWithMessageCredential'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$ADFSBaseUri</span> <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$ADFSBaseUri</span><span style="color: #a9a9a9;">.</span>TrimEnd('/')</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><br /></span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #00008b;">switch</span> (<span style="color: #ff4500;">$ClientCredentialType</span>) {</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; 'Windows' {</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$MessageCredential</span> <span style="color: #a9a9a9;">=</span> 'Windows'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$ADFSTrustEndpoint</span> <span style="color: #a9a9a9;">=</span> 'windowsmixed'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; }</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; 'UserName' {</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$MessageCredential</span> <span style="color: #a9a9a9;">=</span> 'UserName'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$ADFSTrustEndpoint</span> <span style="color: #a9a9a9;">=</span> 'usernamemixed'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; }</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">}</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span>&nbsp;<span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$Credential</span> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: #8a2be2;">System.Net.NetworkCredential</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-ArgumentList</span> <span style="color: #ff4500;">$Username</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$Password</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$Domain</span></span></div>
<br />
<div class="WordSection1"></div>
<div class="WordSection1"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Here we set some initial variables. I&rsquo;ve hardcoded in a reference to the WS-Trust 1.3 endpoints and we&rsquo;ll be using the corresponding WS2007HttpBinding. We&rsquo;ll also be using the TransportWithMessageCredential (aka &ldquo;mixed&rdquo;) SecurityMode. We make sure to remove trailing slashes on the ADFS URL so that formatting works smoothly later. Finally we set variables to be used for the ADFS endpoints and to configure our own client bindings either for Windows or UserName authentication. To make things easier, we create a credential object based on the values passed in by the user.</span></div>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">We&rsquo;ll be using all these variables later in the function. Now it's time to get to work.</span></p>
<br />
<div class="WordSection1"><span style="font-size: small; font-family: 'courier new', courier;"><span style="color: blue;">Add-Type</span> <span style="color: navy;">-AssemblyName</span> 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier;"><span style="font-size: small;"></span><span style="font-size: small;"><span style="color: blue;">Add-Type</span> <span style="color: navy;">-AssemblyName</span> 'System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'</span></span></div>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Here we make sure these assemblies are loaded. They might be already, but it doesn&rsquo;t hurt to load them again. Assemblies can only exist once per AppDomain; each subsequent load does nothing, but also doesn&rsquo;t cause an error.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Time to make the Binding! Bindings in WCF define the channels over which protocol messages will flow, such as whether HTTP, HTTPS, or TCP will be used, whether authentication is required, and whether messages will be sent as plain text or somehow compressed or encoded. Here we start with a prefab binding - the WS2007HttpBinding. This includes most of the elements needed for communicating with a WS-* web service; we just need to set some authentication and security-related parameters.</span></p>
<br />
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;">$Binding</span> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: navy;">-TypeName</span> System.ServiceModel.WS2007HttpBinding `</span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"></span><span style="font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-ArgumentList</span> (<span style="color: #a9a9a9;">[</span><span style="color: teal;">System.ServiceModel.SecurityMode</span><span style="color: #a9a9a9;">]</span> <span style="color: #ff4500;">$SecurityMode</span>)</span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"></span><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;">$Binding</span><span style="color: #a9a9a9;">.</span>Security<span style="color: #a9a9a9;">.</span>Message<span style="color: #a9a9a9;">.</span>EstablishSecurityContext <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$false</span></span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;"></span></span><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;">$Binding</span><span style="color: #a9a9a9;">.</span>Security<span style="color: #a9a9a9;">.</span>Message<span style="color: #a9a9a9;">.</span>ClientCredentialType <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$MessageCredential</span></span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;"></span></span><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;">$Binding</span><span style="color: #a9a9a9;">.</span>Security<span style="color: #a9a9a9;">.</span>Transport<span style="color: #a9a9a9;">.</span>ClientCredentialType <span style="color: #a9a9a9;">=</span> <span style="color: #8b0000;">'None'</span></span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"><span style="color: #8b0000;"></span></span><span style="font-family: 'courier new', courier;"><span style="color: #ff4500;">$EP</span> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: navy;">-TypeName</span> System.ServiceModel.EndpointAddress `</span></span></div>
<div class="WordSection1"><span style="font-size: small;"><span style="font-family: 'courier new', courier;"></span><span style="font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-ArgumentList</span> (<span style="color: #8b0000;">'{0}/{1}/{2}'</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$ADFSBaseUri</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$ADFSTrustPath</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$ADFSTrustEndpoint</span>)</span></span></div>
<br />
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; background: white; text-autospace: none;"><span style="font-size: 9.0pt; font-family: 'Lucida Console'; color: darkred;">&nbsp;</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">We set the security mode to be TransportWithMessageCredential (using the variable set earlier). We specify not to set a persistent security context, which would use WS-SecureConversation and set up a Session token, a complication we don&rsquo;t want right now. The message client credential type will be either Windows or UserName, depending on what we set earlier, and we don&rsquo;t add any credentials at the transport (i.e. HTTP) layer.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">We also create an Endpoint Address, which represents the address which the service is listening on, based on the parameters passed in by the caller.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">With our Binding and Endpoint Address prepared, we&rsquo;re nearly ready to combine them and build a WS-Trust protocol client. To do so, we&rsquo;ll start by building a client factory. As its name implies, the factory will be able to churn out the actual client (also known as a &lsquo;channel&rsquo;) to do our work.</span></p>
<br />
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$WSTrustChannelFactory</span> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: navy;">-TypeName</span> System.ServiceModel.Security.WSTrustChannelFactory `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: navy;">&nbsp; &nbsp; -ArgumentList</span> <span style="color: #ff4500;">$Binding</span><span style="color: #a9a9a9;">,</span> <span style="color: #ff4500;">$EP</span></span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;"></span></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$WSTrustChannelFactory</span><span style="color: #a9a9a9;">.</span>TrustVersion <span style="color: #a9a9a9;">=&nbsp;</span><span style="color: teal;">System.ServiceModel.Security.TrustVersion</span><span style="color: #a9a9a9;">]::</span>WSTrust13</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$WSTrustChannelFactory</span><span style="color: #a9a9a9;">.</span>Credentials<span style="color: #a9a9a9;">.</span>Windows<span style="color: #a9a9a9;">.</span>ClientCredential <span style="color: #a9a9a9;">=&nbsp;</span><span style="color: #ff4500;">$Credential</span></span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;"></span></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$WSTrustChannelFactory</span><span style="color: #a9a9a9;">.</span>Credentials<span style="color: #a9a9a9;">.</span>UserName<span style="color: #a9a9a9;">.</span>UserName <span style="color: #a9a9a9;">=&nbsp;</span><span style="color: #ff4500;">$Credential</span><span style="color: #a9a9a9;">.</span>UserName</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$WSTrustChannelFactory</span><span style="color: #a9a9a9;">.</span>Credentials<span style="color: #a9a9a9;">.</span>UserName<span style="color: #a9a9a9;">.</span>Password <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$Credential</span><span style="color: #a9a9a9;">.</span>Password</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$Channel</span> <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$WSTrustChannelFactory</span><span style="color: #a9a9a9;">.</span>CreateChannel()</span></div>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">The first line builds our factory, which combines the WS-Trust protocol with the binding and endpoint address we already created. Next we specify a trust version and credentials to use for channels created by this factory. The astute amongst you will notice we set both a Windows and UserName credential here, even though we&rsquo;ll actually only use on or the other. It doesn&rsquo;t hurt to add them both. Once we've built and configured our factory, we tell it to create us a channel!</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Channel in hand, we now need to construct a RST (RequestSecurityToken) to send to ADFS.</span></p>
<br />
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #ff4500;">$TokenType</span><span style="line-height: 110%;"> <span style="color: #a9a9a9;">=</span> @{</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; SAML11 <span style="color: #a9a9a9;">=</span> <span style="color: #8b0000;">'urn:oasis:names:tc:SAML:1.0:assertion'</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; SAML2 <span style="color: #a9a9a9;">=</span> <span style="color: #8b0000;">'urn:oasis:names:tc:SAML:2.0:assertion'</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">}</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #ff4500;">$RST</span><span style="line-height: 110%;"> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: navy;">-TypeName</span> <span style="color: #8a2be2;">System.IdentityModel.Protocols.WSTrust.RequestSecurityToken</span> <span style="color: navy;">-Property</span> @{</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp; &nbsp;RequestType&nbsp;<span style="color: #a9a9a9;">=</span> <span style="color: #a9a9a9;">[</span><span style="color: teal;">System.IdentityModel.Protocols.WSTrust.RequestTypes</span><span style="color: #a9a9a9;">]::</span>Issue</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp; &nbsp;AppliesTo &nbsp; <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$AppliesTo</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp; &nbsp;KeyType &nbsp; &nbsp; <span style="color: #a9a9a9;">=</span> <span style="color: #a9a9a9;">[</span><span style="color: teal;">System.IdentityModel.Protocols.WSTrust.KeyTypes</span><span style="color: #a9a9a9;">]::</span>Bearer</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp; &nbsp;TokenType &nbsp; <span style="color: #a9a9a9;">=</span> <span style="color: #00008b;">if</span> (<span style="color: #ff4500;">$SAMLVersion</span> <span style="color: #a9a9a9;">-eq</span> <span style="color: #8b0000;">'2'</span>) {<span style="color: #ff4500;">$TokenType</span><span style="color: #a9a9a9;">.</span>SAML2} <span style="color: #00008b;">else</span> {<span style="color: #ff4500;">$TokenType</span><span style="color: #a9a9a9;">.</span>SAML11}</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">}</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="color: #ff4500;">$RSTR</span> <span style="color: #a9a9a9;">=</span> <span style="color: blue;">New-Object</span> <span style="color: navy;">-TypeName</span> <span style="color: #8a2be2;">System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse</span></span></p>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">In the first command, we create a Hashtable to represent the two token types we&rsquo;re prepared to retrieve. This is just to keep things clearer later on as you'll see. Next, we create the RST object and set its properties via a Hashtable passed for the -Property parameter. If this looks too convoluted in your browser, perhaps copy it out into the ISE. The RequestType is the WS-Trust 'Issue' protocol and we are requesting a Bearer key. The TokenType is set to SAML2 or SAML11 depending on the user&rsquo;s selection; and the AppliesTo property is set to the specified Relying Party. In the last command, we create an empty RSTR object to hold the RSTR which ADFS will return.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Now we&rsquo;re ready to use our RST in a request.</span></p>
<br />
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #00008b;">try</span><span style="line-height: 110%;"> {</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$OriginalCallback</span> <span style="color: #a9a9a9;">=</span> <span style="color: #a9a9a9;">[</span><span style="color: teal;">System.Net.ServicePointManager</span><span style="color: #a9a9a9;">]::</span>ServerCertificateValidationCallback</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: #00008b;">if</span> (<span style="color: #ff4500;">$IgnoreCertificateErrors</span><span style="color: #a9a9a9;">.</span>IsPresent) {</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; text-indent: .5in; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #a9a9a9;">[</span><span style="line-height: 110%; color: teal;">System.Net.ServicePointManager</span><span style="line-height: 110%; color: #a9a9a9;">]::</span><span style="line-height: 110%;">ServerCertificateValidationCallback <span style="color: #a9a9a9;">=</span> {<span style="color: #00008b;">return</span> <span style="color: #ff4500;">$true</span>}</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: #ff4500;">$Token</span> <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$Channel</span><span style="color: #a9a9a9;">.</span>Issue(<span style="color: #ff4500;">$RST</span><span style="color: #a9a9a9;">,</span> <span style="color: #a9a9a9;">[</span><span style="color: teal;">ref</span><span style="color: #a9a9a9;">]</span> <span style="color: #ff4500;">$RSTR</span>)</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">}</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #00008b;">finally</span><span style="line-height: 110%;"> {</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: #a9a9a9;">[</span><span style="color: teal;">System.Net.ServicePointManager</span><span style="color: #a9a9a9;">]::</span>ServerCertificateValidationCallback <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$OriginalCallback</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">} </span></p>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">As mentioned in the list of parameters, I wanted this function to work okay even with certificates not signed by a globally-trusted CA, so I&rsquo;ve added a way to bypass certificate checking. Because this modification effects the entire PowerShell process, even after our function has completed, I&rsquo;ve added some elements to make sure the change is only in effect during our service call and is then reverted. Wrapping this all in a try/finally block ensures that even if something goes wrong with the request, the certificate validation bypass is still reverted.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">The main work here is done when we call Issue on the channel we created previously. We pass in the RST we created and receive back an RSTR and a processed SecurityToken from ADFS. The RSTR is stored in the out parameter $RSTR, and the SecurityToken is stored in $Token.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Now all that&rsquo;s left is to return what the user asked for.</span></p>
<br />
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: #00008b;">if</span><span style="line-height: 110%;"> (<span style="color: #ff4500;">$OutputType</span> <span style="color: #a9a9a9;">-eq</span> <span style="color: #8b0000;">'RSTR'</span>) {</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">Write-Output</span> <span style="color: navy;">-InputObject</span> <span style="color: #ff4500;">$RSTR</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">} <span style="color: #00008b;">else</span> {</span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">Write-Output</span> <span style="color: navy;">-InputObject</span> <span style="color: #ff4500;">$Token</span></span></p>
<p class="MsoNormal" style="margin: 0in; margin-bottom: .0001pt; line-height: 110%; background: white; text-autospace: none;"><span style="font-size: small; line-height: 110%; font-family: 'courier new', courier;">} </span></p>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">These lines are pretty self-explanatory. If the user asked for an RSTR that&rsquo;s what we return; if he/she wants the processed token, that&rsquo;s what they get.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">With our function declared and explained, we&rsquo;re ready to test it out against our server. Don't forget, you can <a href="http://gallery.technet.microsoft.com/scriptcenter/Invoke-ADFSSecurityTokenReq-09e9c90c" target="_blank">download the complete script from the TechNet Script Gallery</a>. Here&rsquo;s what calling it could look like:</span></p>
<br />
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%; color: blue;">Invoke-ADFSSecurityTokenRequest</span><span style="line-height: 110%;"> `</span></span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"><span style="line-height: 110%;"> </span></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-ClientCredentialType</span> <span style="color: #8a2be2;">UserName</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-ADFSBaseUri</span> <span style="color: #8a2be2;">https://corp.sts.microsoft.com</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-AppliesTo</span> <span style="color: #8a2be2;">https://activedirectory.windowsazure.com</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-UserName</span> <span style="color: #8b0000;">'joshgav'</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-Password</span> <span style="color: #8b0000;">'MyPassword'</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-Domain</span> <span style="color: #8b0000;">'CORP'</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-OutputType</span> <span style="color: #8a2be2;">Token</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; <span style="color: navy;">-SAMLVersion</span> <span style="color: purple;">2</span> `</span></div>
<div class="WordSection1"><span style="font-family: 'courier new', courier; font-size: small;"></span><span style="color: navy; font-family: 'courier new', courier; font-size: small;">&nbsp;&nbsp;&nbsp; -IgnoreCertificateErrors </span></div>
<br />
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Here I&rsquo;m requesting a token from Microsoft&rsquo;s corporate ADFS STS to apply to Azure Active Directory. I supply my username and password (names changed to protect the innocent) and receive a SAML 2 token in return.</span></p>
<p class="MsoNormal"><span style="font-family: tahoma, arial, helvetica, sans-serif;">Your next step should be to assign the SecurityToken or RSTR output from the function to a variable and explore its properties. I also recommend turning on Fiddler in the background while you execute the function and checking out the request and response.</span></p>
</div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/36/02/37/Invoke-SecurityTokenRequest.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-36-02-37/Invoke_2D00_SecurityTokenRequest.zip">Invoke-SecurityTokenRequest.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>The SharePoint Federation Authentication Module (SPFAM)</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/the-sharepoint-federation-authentication-module-spfam</link>
      <pubDate>Thu, 24 May 2012 06:33:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/05/24/the-sharepoint-federation-authentication-module-spfam/</guid>
      <description><![CDATA[SharePoint Claims Authentication Series
01 - SharePoint, Claims, WS-* and the Windows Identity...]]></description>
      <content:encoded><![CDATA[<h1>SharePoint Claims Authentication Series</h1>
<p><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/02/sharepoint-claims-ws-and-the-windows-identity-foundation-wif.aspx">01 - SharePoint, Claims, WS-* and the Windows Identity Foundation (WIF)</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/10/ws-federation-authentication-module-wsfam-and-sharepoint-extensions.aspx">02 - WS-Federation Authentication Module and SharePoint Extensions</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/24/the-sharepoint-federation-authentication-module-spfam.aspx">03 - The SharePoint Federation Authentication Module</a><br />04 - Integrating SharePoint with Windows Azure Active Directory (ACS)<br />05 - Session Authentication Module and WS-SecureConversation<br />06 - SharePoint Session Authentication Module<br />07 - Windows Claims Authentication<br />08 - Service (ActAs) Tokens</p>
<p><em>Thank you to <a href="http://blogs.technet.com/b/speschka/">Steve Peschka</a> for reviewing these articles! </em></p>
<h1>SharePoint Claims Authentication Part 3</h1>
<p>Cool as WIF is, this series is meant to help with understanding SharePoint authentication in particular. So in this article we will build on the foundation laid in the first two and describe how the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.identitymodel.spfederationauthenticationmodule.aspx">SharePoint Federation Authentication Module</a> complements and extends WIF's WSFAM.</p>
<p>For the sake of being complete, I'll mention here that the first thing the SPFAM does is hook up SharePoint's custom certificate validation process, so that root certificates are checked against the collection stored in SharePoint in addition to the local machine store. SharePoint has its own built-in Certificate Authority; you can retrieve a list of trusted root certificates via Get-SPTrustedRootAuthority and add new ones with Add-SPTrustedRootAuthority.</p>
<p>Moving on, the two points where SPFAM diverges significantly from its WSFAM roots are: 1) in the process of initial redirection of the web browser when it first contacts a SharePoint web application; and 2) in the process of setting up the Session Security Token after authentication has completed in the second communication between browser and web application (after the browser is redirected back to the application). We'll focus in this article on how SharePoint handles initial redirection to an STS and return to session tokens later. It is important to emphasize that if Windows Claims and only Windows Claims is enabled for a Web Application, a different process is followed which we will cover later in its own article.</p>
<h2>First Redirections</h2>
<p>Assuming Windows Claims is not enabled, SharePoint starts by causing two sequential redirections to take place. As with all the interactions described above and below, you can follow along at home in <a href="http://www.fiddler2.com/fiddler2/">Fiddler</a>. The first two redirections are to:</p>
<ol>
<li>/_layouts/Authenticate.aspx</li>
<li>/_login/default.aspx</li>
</ol>
<p>The redirection to Authenticate.aspx leads to a page which tries one last time to authenticate the incoming user. I'm not sure why this is here, but perhaps we'll figure it out as we continue or perhaps a reader will know and tip us off. I believe it may help with authentication on the return trip, where our browser will visit this page again. The second redirection is initiatied by the <a href="http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationmodule.aspx">FormsAuthenticationModule</a> based on the following <a href="http://msdn.microsoft.com/en-us/library/1d3t3c61.aspx">entry in web.config</a>:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: small;">&lt;authentication mode="Forms"&gt;<br />&nbsp; &lt;forms loginUrl="/_login/default.aspx" /&gt;<br />&lt;/authentication&gt; </span></p>
<h2>Home Realm Discovery</h2>
<p>At /_login/default.aspx the fun continues! This page is known as the MultiLogonPage and is responsible for a process called <a href="http://blogs.msdn.com/b/vbertocci/archive/2009/04/08/one-does-not-simply-walk-into-mordor-or-home-realm-discovery-for-the-internet.aspx">Home Realm discovery</a>. We've referred to the URL of the SharePoint (or other) web application as the Trusting Realm. A user's Home Realm is the realm and associated STS which have first-hand knowledge of the user and are willing and capable of ascertaining and attesting to the user's identity. For example, as a Microsoft employee my home realm is generally microsoft.com. Determining a user's home realm is not always a trivial process and unfortunately sometimes requires direct user interaction. That is the case in SharePoint if more than one authentication provider has been specified for a Web Application, and is the purpose of the MultiLogon page. If more than one authentication provider has been configured, the user will be presented here with a drop-down box from which to choose their home realm - the realm which is capable of authenticating him or her.</p>
<p>As an aside, other options have been proposed for home realm discovery in SharePoint, such as those documented by Steve Peschka <a href="http://blogs.technet.com/b/speschka/archive/2011/09/14/using-the-whr-parameter-with-sharepoint-2010-and-saml-auth.aspx">here</a> and <a href="http://blogs.technet.com/b/speschka/archive/2011/04/30/bypassing-the-multi-authentication-provider-selection-page-in-sharepoint-2010.aspx">here</a> and Chris Keyser <a href="http://blogs.msdn.com/b/chriskeyser/archive/2011/10/02/sharepoint-2010-claims-and-home-realm-discover-passing-whr-on-the-url-to-sharepoint.aspx">here</a>.</p>
<p>Luckily, in situations where only one authentication provider has been configured, the MultiLogonPage is smart enough to continue the process of sending the user to the proper STS without having to bother them further. In either case (that is, whether the STS is determined automatically or the user chooses a realm and associated STS from the dropdown), the next step is to redirect the user to the AuthenticationRedirectionUrl associated with that STS. To review these redirection URLs, you can run <strong>Get-SPAuthenticationProvider</strong> in PowerShell and check the AuthenticationRedirectionUrl property. As you will see, this next redirection is again within the SharePoint application and is the last one before we leave for our STS. In a Web Application of mine configured with a single authentication provider, here's the output of that command and the next step in our journey:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: small;">PS:&gt; Get-SPAuthenticationProvider -WebApplication https://intranet.gavant.local -Zone Default<br /><br />DisplayName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : AzureACS<br />LoginProviderName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : AzureACS<br />ClaimProviderName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: <br />AuthenticationRedirectionUrl : /_trust/default.aspx?trust=AzureACS<br />UpgradedPersistedProperties&nbsp; : </span></p>
<p>And yes, before all is said and done we will walk through federating a SharePoint web application with Azure ACS. Let's explore what happens in this step. The page (_trust/default.aspx) and it's web.config are stored at 14\TEMPLATE\IDENTITYMODEL\TRUST.</p>
<h2>Off to the STS</h2>
<p>The key logic on this page checks the "trust" parameter of the incoming query string and prepares to finally redirect the browser to the actual STS associated with the named Trusted Provider. Note that the name of my Trusted Provider is AzureACS. If I run Get-SPTrustedIdentityTokenIssuer, I retrieve all information needed to send a WS-Federation request to that trusted provider, as shown here:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: small;">PS:&gt; Get-SPTrustedIdentityTokenIssuer<br /><br />ProviderUri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : https://joshgav.accesscontrol.windows.net/v2/wsfederation<br />DefaultProviderRealm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;: https://intranet.gavant.local<br />ProviderRealms&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {}<br />ClaimTypes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier, http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/IdentityProvider}<br />HasClaimTypeInformation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<br />ClaimTypeInformation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {ACSNameIdentifier, ACSIdentityProvider}<br />IdentityClaimTypeInformation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Microsoft.SharePoint.Administration.Claims.SPTrustedClaimTypeInformation<br />ClaimProviderName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : <br />UseWReplyParameter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : False<br />Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : AzureACS<br />SigningCertificate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp; [Subject]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CN=joshgav.accesscontrol.windows.net<br /> <br />&nbsp; [Issuer]<br />&nbsp;&nbsp; CN=joshgav-ca, DC=joshgav, DC=com<br /> <br />&nbsp; [Serial Number]<br />&nbsp;&nbsp; 2F3422D100000000000A<br /> <br />&nbsp; [Not Before]<br />&nbsp;&nbsp; 3/28/2012 10:59:41 AM<br /> <br />&nbsp; [Not After]<br />&nbsp;&nbsp; 3/28/2014 10:59:41 AM<br /> <br />&nbsp; [Thumbprint]<br />&nbsp;&nbsp; F8EA661189C2B1B6098B44EEB9427B2969A4FA23<br /> <br />Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: AzureACS<br />TypeName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Microsoft.SharePoint.Administration.Claims.SPTrustedLoginProvider<br />DisplayName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : AzureACS<br />Id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 24c187f3-22cb-4bb9-a45c-fc31a786a1ad<br />Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Online<br />Parent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SPSecurityTokenServiceManager Name=SecurityTokenServiceManager<br />Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 3381307<br />Properties&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {}<br />Farm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SPFarm Name=SPS2010RTM_SharePoint_Configuration_Database<br />UpgradedPersistedProperties&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;: {} </span></p>
<p>And using this information, that's exactly what is done! This info is built into the proper WS-Federation URL with query string and my browser is redirected to the appropriate STS where the next stage in the WS-Federation profile can take place. After that is complete, the RSTR is posted back to this same location (/_trust/) and the AuthenticateRequest stage of the standard WSFAM is invoked as described before to complete the authentication process. The full sequence of HTTP requests (copied from Fiddler) is shown here (click for a larger view):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5025.SharePointToSTSToSharePointRedirection.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5025.SharePointToSTSToSharePointRedirection.PNG"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/5025.SharePointToSTSToSharePointRedirection.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/5025.SharePointToSTSToSharePointRedirection.PNG" /></a></p>
<p>Note that in the two messages where a 200 is received followed by a POST in the next message, most details have been included in a form which is posted to the next hop. In the other GET requests information is sent to the next hop in the query string.</p>
<h1>Conclusion</h1>
<p>Congratulations! If you've come this far you are pretty well equipped to understand the Claims logon process in a SharePoint web application. There is still quite a ways to go, as we have yet to discuss Session and Security Context Tokens, the special case of Windows claims, and how claims works for service applications, but there is always another day <span style="font-family: Wingdings;">J</span>. In my next post, we'll take time for some fun practical application and I'll walk you through federating a SharePoint web application with Azure Access Control Service with the usual commentary along the way. As a bonus, we'll do it completely via PowerShell. In the meantime, rest your head!</p>]]></content:encoded>
    </item>
    <item>
      <title>WS-Federation Authentication Module (WSFAM) and SharePoint Extensions</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/ws-federation-authentication-module-wsfam-and-sharepoint-extensions</link>
      <pubDate>Thu, 10 May 2012 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/05/10/ws-federation-authentication-module-wsfam-and-sharepoint-extensions/</guid>
      <description><![CDATA[SharePoint Claims Authentication Series
01 - SharePoint, Claims, WS-* and the Windows Identity...]]></description>
      <content:encoded><![CDATA[<h1>SharePoint Claims Authentication Series</h1>
<p><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/02/sharepoint-claims-ws-and-the-windows-identity-foundation-wif.aspx">01 - SharePoint, Claims, WS-* and the Windows Identity Foundation (WIF)</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/10/ws-federation-authentication-module-wsfam-and-sharepoint-extensions.aspx">02 - WS-Federation Authentication Module and SharePoint Extensions</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/24/the-sharepoint-federation-authentication-module-spfam.aspx">03 - The SharePoint Federation Authentication Module<br /></a>04 - Integrating SharePoint with Windows Azure Active Directory (ACS)<br />05 - Session Authentication Module and WS-SecureConversation<br />06 - SharePoint Session Authentication Module<br />07 - Windows Claims Authentication<br />08 - Service (ActAs) Tokens</p>
<p><em>Thank you to <a href="http://blogs.technet.com/b/speschka/">Steve Peschka</a> for reviewing these articles! </em></p>
<h1>SharePoint Claims Authentication Part 2</h1>
<p>In the Windows Identity Foundation (WIF) and Claims web applications utilizing it, the WS-Federation Authentication Module (WSFAM) and Session Authentication Module (SAM) are responsible for authentication. Like existing authentication modules for IIS and ASP.NET such as the Windows Authentication and Forms Authentication modules, the WIF authentication modules plug into stages in the integrated pipeline to interact with and influence request processing.</p>
<h1>SharePoint implementation of WSFAM and SAM</h1>
<p>As in so many other areas, SharePoint wraps and simplifies management of Claims authentication via WIF. It does this by deriving custom classes from the standard WSFAM and SAM authentication modules: the SPFederationAuthenticationModule and SPSessionAuthenticationModule, respectively. SharePoint also adds a third module to the pipeline, SPWindowsClaimsAuthenticationHttpModule, which deals specifically with creating Claims-based tokens for Windows users. More on that later. The extensions to the web.config files when Claims authentication is enabled are contained within 14\CONFIG\IdentityModel\webconfig.identitymodel.add.xml; the new modules appear like this in a Web Application's web.config file:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">&lt;add name="FederatedAuthentication" type="Microsoft.SharePoint.IdentityModel.SPFederationAuthenticationModule, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt;<br />&lt;add name="SessionAuthentication" type="Microsoft.SharePoint.IdentityModel.SPSessionAuthenticationModule, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt;<br />&lt;add name="SPWindowsClaimsAuthentication" type="Microsoft.SharePoint.IdentityModel.SPWindowsClaimsAuthenticationHttpModule, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt; </span></p>
<p>Some settings for Claims authentication can be configured declaratively in web.config files like some settings of the Forms, Windows, and other authentication modules. The &lt;microsoft.identityModel&gt; section is used to declare these settings and is added as a direct child of the &lt;configuration&gt; element. In SharePoint web.config files it tends to be at the very bottom of the file. The default configuration for SharePoint web applications is provided in the same XML file as the additional module configuration described above and is provided below for reference. I'd highly recommend not changing this without clear approval or instruction from Microsoft Support. Some of these settings may be surprising, such as passiveRedirectEnabled="false", but as we shall see their values have been chosen for a reason.</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;"> &lt;microsoft.identityModel&gt;<br />&nbsp;&nbsp;&nbsp;&lt;service saveBootstrapTokens="true"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;audienceUris /&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp; &lt;issuerNameRegistry type="Microsoft.SharePoint.IdentityModel.SPPassiveIssuerNameRegistry, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;securityTokenHandlers&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;clear /&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add type="Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;add type="Microsoft.SharePoint.IdentityModel.SPSaml11SecurityTokenHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;samlSecurityTokenRequirement&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;nameClaimType value="http://schemas.microsoft.com/sharepoint/2009/08/claims/userid" /&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/samlSecurityTokenRequirement&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;/add&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add type="Microsoft.SharePoint.IdentityModel.SPTokenCache, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp; &lt;/securityTokenHandlers&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;federatedAuthentication&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;wsFederation passiveRedirectEnabled="false" issuer="https://none" realm="https://none" /&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;cookieHandler mode="Custom" path="/"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;customCookieHandler type="Microsoft.SharePoint.IdentityModel.SPChunkedCookieHandler, Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/cookieHandler&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp; &lt;/federatedAuthentication&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/service&gt;<br /> &lt;/microsoft.identityModel&gt; </span></p>
<p>Of the various <a href="http://msdn.microsoft.com/en-us/library/4wt3wttw(v=vs.100).aspx">stages in the ASP.NET pipeline</a> (see the Remarks section at the end of the linked page), you will not be surprised to learn that the two WIF authentication modules register for the AuthenticateRequest and PostAuthenticateRequest events. You may be surprised that the WSFAM module registers for the EndRequest event as well. We'll now explain how these modules work, beginning with WSFAM and SPFAM. In this post, we'll describe WSFAM independently and in the next article describe how SharePoint modifies its behavior.</p>
<h1>WSFAM: The federation sequence</h1>
<p>As its name implies, the WS-Federation Authentication Module is responsible for implementing the WS-Federation profile to request and receive security tokens via a web browser (passive) client. In simple WIF applications, properties such as the federated STS, the source realm, and the desired authentication type can be set in the web.config file at the path <em>configuration/microsoft.identityModel/service/federatedAuthentication/wsFederation</em> as detailed <a href="http://msdn.microsoft.com/en-us/library/gg638729.aspx">here</a>. If you're familiar with the WS-Federation spec you'll immediately recognize the correspondence between query parameters specified therein and the configuration properties available for WSFAM.</p>
<p>web.config-based configuration of WSFAM allows federation with a single Security Token Service. This may be fine for small applications, but in SharePoint more options are needed. As a result, the wsFederation element for a SharePoint web application is filled mostly with placeholder content. Instead of using this element, SharePoint retrieves details about federation configuration and requirements from its own object model in the SPFAM module process, as we'll discuss later.</p>
<h2>AuthenticateRequest</h2>
<p>As mentioned above, WSFAM registers itself for the AuthenticateRequest pipeline event. Logically and intuitively, the WSFAM passes through this stage first. However, the actions taken at this stage differ significantly on the second time through the pipeline, so we will address the stages of WSFAM as follows:</p>
<ol>
<li>AuthenticateRequest (first pass)</li>
<li>PostAuthenticateRequest</li>
<li>EndRequest</li>
<li>AuthenticateRequest (second pass)</li>
</ol>
<p>As it passes through the AuthenticateRequest stage, the WSFAM checks the incoming request for a form with a wresult parameter. If you recall from part one of this series, the RSTR from the STS is returned to the Relying Party (RP) application embedded in this wresult form parameter. So in other words, this stage expects to take action only if the browser has already visited and returned from the STS with a security token. That will be the case later on, in the second pass (stage 4). However, if this is the browser's first contact with the web application, the AuthenticateRequest process in WSFAM will not find a wresult parameter and will thus have nothing to do.</p>
<h2>PostAuthenticateRequest</h2>
<p>In the PostAuthenticateRequest stage, WSFAM checks if a Claims principal has been properly set on the current HTTP context. If authentication succeeded in the AuthenticateRequest stage some principal will have been set on the context, though this principal could be a Windows or Forms principal and not a Claims principal. In that case, the WSFAM converts them into a Claims Principal at this stage. If no principal has been set (i.e. authentication has not yet succeeded), an <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.claims.claimsprincipal.anonymousprincipal.aspx">anonymous Claims principal</a> is set for the context now. In SharePoint, either a Claims principal should already have been set at this point (if authentication has completed, i.e. during the second pass) or the anonymous principal will be set.</p>
<p>After a proper Claims principal has been set on the context, any custom <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.claims.claimsauthenticationmanager.aspx">Claims Authentication Manager</a> configured for the application is called. For SharePoint web applications, no Claims Authentication Manager is configured; however, there is a custom Claims Authentication Manager for service applications. Claims Authentication Managers can modify or augment claims set for the incoming principal, or even entirely replace that principal. This may be a valid extensibility point even in a SharePoint web application; however, a <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.claims.spclaimprovider.aspx">custom ClaimProvider</a> would generally be more appropriate.</p>
<h2>EndRequest</h2>
<p>Finally, we arrive at the EndRequest stage, which is the most significant point on a request's first pass through the pipeline. It is at this point that the browser is redirected to an STS to request a security token. Significantly, by default this entire stage is skipped if the passiveRedirectEnabled property on the wsFederation configuration element is set to "false". As you can see in the configuration above, this is in fact the case for a SharePoint web application. SharePoint provides its own version of OnEndRequest to inject the more complex logic needed there. Let's go ahead and look at what WSFAM does on its own first.</p>
<p>First, EndRequest checks if the incoming request is not authorized by checking for a 401 response code. Thus, this stage is generally only relevant on the first pass through the pipeline. Of course, it's possible that a user was properly authenticated but still not authorized to access the target resource, so EndRequest also checks if an authenticated user has been set on the context. If it hasn't, redirection to the STS is initiated. This is pretty simple - parameters set declaratively and programmatically for the request to the STS are gathered together and placed in a query string, itself appended to the URL of the designated STS. This URL is sent to the browser as a 302 response and the browser heads off to the STS to request a security token, as described in Part 1.</p>
<p>The next step at this point in the WS-Federation profile is authentication at the STS, receipt of a security token from the STS, and posting of that token back to the RP web application. See the first post in this series for more elaboration on these details. Once the RSTR is posted back to the RP web application, we reach the AuthenticateRequest stage in the ASP.NET pipeline again, and we continue our discussion there.</p>
<h2>AuthenticateRequest (second pass)</h2>
<p>Coming through AuthenticateRequest after returning from the STS, the browser should now be presenting a form with a valid wresult parameter containing an RSTR (RequestSecurityTokenResponse). This time through WSFAM has a lot to do! It must read in the RSTR, find and call appropriate security token handlers, and finally pass off control to the Session Authentication Manager to create a session security token. Let's step through this process step by step.</p>
<p>First, the web form in the incoming request is parsed. The wresult parameter, which contains the RSTR and associated security token, is the most important component here. It is retrieved and then passed to the collection of SecurityTokenHandlers specified in the web.config file (or programmatically). <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.securitytokenhandler.aspx">SecurityTokenHandlers</a> are elements in Windows Identity Foundation responsible for reading the raw, serialized Security Token XML and converting it into a <a href="http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytoken.aspx">SecurityToken</a> object. In the simplest case (such as in SharePoint), a single collection of SecurityTokenHandlers is associated with a web application in its web.config file. Incoming tokens are passed to the configured handlers one by one in order, and the first one that can successfully parse the XML returns a valid SecurityToken object. If you review the snippet from the microsoft.identityModel section of SharePoint's web.config above you'll find that the three token handlers configured in SharePoint 2010 are (in order):</p>
<ol>
<li>Microsoft.IdentityModel.Tokens.X509SecurityTokenHandler</li>
<li>Microsoft.SharePoint.IdentityModel.SPSaml11SecurityTokenHandler</li>
<li>Microsoft.SharePoint.IdentityModel.SPTokenCache</li>
</ol>
<p>The types of tokens handled by the first two entries are self-evident. The X509 handler is used to parse the signing certificate of incoming SAML tokens and the SAML1.1 handler parses the actual SAML tokens themselves. The SPTokenCache handler is a special handler for managing session security tokens (aka Security Context Tokens, or SCTs). We'll get to those when we get to the Session Authentication Module.</p>
<p>Once the SecurityToken is created from the RSTR, it's used to create a Claims principal. This principal is passed through any custom ClaimsAuthenticationManager (described above) to leave us with the final Claims principal that will be set on the HTTP and thread context for ongoing use in the web application.</p>
<h1>What's Next?</h1>
<p>And we're done! Well, not quite&hellip; Didn't think it was that easy did you? If this were the end, you'd have to re-authenticate each time you requested a new page in the web application. Fortunately, we create a special Session Security Token that can be used to maintain a single authenticated secure conversation across multiple messages. This is the responsibility of the Session Authentication Module, which we'll leave for another article.</p>
<h1>Conclusion</h1>
<p>Hopefully you now understand how WIF implements the passive requestor pipeline defined in the WS-Federation spec. In the next article, we'll cover the modifications SharePoint makes to this process.</p>]]></content:encoded>
    </item>
    <item>
      <title>SharePoint, Claims, WS-* and the Windows Identity Foundation (WIF)</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/sharepoint-claims-ws-and-the-windows-identity-foundation-wif</link>
      <pubDate>Thu, 03 May 2012 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/05/03/sharepoint-claims-ws-and-the-windows-identity-foundation-wif/</guid>
      <description><![CDATA[SharePoint Claims Authentication Series
01 - SharePoint, Claims, WS-* and the Windows Identity...]]></description>
      <content:encoded><![CDATA[<h1>SharePoint Claims Authentication Series</h1>
<p><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/02/sharepoint-claims-ws-and-the-windows-identity-foundation-wif.aspx">01 - SharePoint, Claims, WS-* and the Windows Identity Foundation (WIF)</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/10/ws-federation-authentication-module-wsfam-and-sharepoint-extensions.aspx">02 - WS-Federation Authentication Module and SharePoint Extensions</a><br /><a href="http://blogs.msdn.com/b/besidethepoint/archive/2012/05/24/the-sharepoint-federation-authentication-module-spfam.aspx">03 - The SharePoint Federation Authentication Module<br /></a>04 - Integrating SharePoint with Windows Azure Active Directory (ACS)<br />05 - Session Authentication Module and WS-SecureConversation<br />06 - SharePoint Session Authentication Module<br />07 - Windows Claims Authentication<br />08 - Service (ActAs) Tokens</p>
<p><em>Thank you to <a href="http://blogs.technet.com/b/speschka/">Steve Peschka</a> for reviewing these articles! </em></p>
<h1>SharePoint Claims Authentication Part 1</h1>
<p>SharePoint 2010 introduced Claims authentication based on the WS-Trust, WS-Federation, and SAML standards, bringing new opportunities for federation, authentication, and authorization scenarios. It also brought a brave new world of concepts and patterns for SharePoint administrators and developers to learn and master. In this series of articles, I'll take you on a deep dive through the mechanisms of the Windows Identity Foundation (WIF) Claims authentication pipeline with a special focus on its application to SharePoint. By understanding these from the inside out I hope you'll be better prepared to implement, maintain, extend and troubleshoot SharePoint, Azure, and O365 integration and federation and maximize your organization's investments in these and other products. As we progress I hope you'll not only find yourself better understanding Claims authentication within SharePoint, but also better understanding Claims authentication in general.</p>
<h1>Why Claims?</h1>
<p>You may be forgiven at this point for asking why. Kerberos has been a relatively stable protocol for many years and is still supported in SharePoint and other Windows applications. NTLM, warts and all, continues to function effectively in many environments. Nevertheless, several factors should drive you to seriously consider Claims authentication.</p>
<p>First, Kerberos and NTLM haven't been significantly updated in many years. Claims and complementary security protocols such as OAuth, OpenID and SAML offer new ways to delegate authentication, authorization, and user profile and attribute information in ways not possible with only the older protocols. Second, NTLM and Kerberos in Windows are not particularly well-suited for interoperation with other applications and systems. Within a single organization Windows authentication alone may be effective; but when federating with other organizations and working across the Internet, SAML and other Claims-based forms of authentication are a more common and supported option. Even within organizations, Claims significantly improves interoperability and coordination between Windows applications such as SharePoint and non-Windows applications and systems. For example, SharePoint's Business Connectivity Services leverage the interoperability made possible by Claims authentication to allow data from external LOB applications to be integrated with SharePoint.</p>
<p>Finally, Claims Authentication is not only the wave of the future, it's already well-established in the present. Microsoft and non-Microsoft systems and services alike utilize and offer Claims-based authentication already. <a href="http://www.windowsazure.com/en-us/home/features/access-control/">Windows Azure Active Directory</a> (aka Azure Access Control Service) and <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=10909">Active Directory Federation Services</a> (ADFS) are based on Claims authentication. In .NET 4.5, the Claims Principal will become the base identity for all threads (as detailed in Vittorio Bertocci's blog post <a href="http://blogs.msdn.com/b/vbertocci/archive/2012/03/15/windows-identity-foundation-in-the-net-framework-4-5-beta-tools-samples-claims-everywhere.aspx">here</a>). On the Internet, when you sign in to Windows Live ID or grant access to your Facebook profile you are utilizing WS-Federation and OAuth. To allow your applications, SharePoint included, to interoperate with all these other systems and services, using and understanding Claims authentication is a necessity.</p>
<h1>The Claims Authentication Stack</h1>
<p>Claims authentication is a process involving many participants and components. While many blog posts and technical articles are available to help you set up Claims authentication in SharePoint and other applications, my goal in this series is to take you on a step-by-step journey through all the components and protocols involved. If I miss something or you disagree with the way I describe things let me know in the comments and I'll respond or amend the content as appropriate. Occasionally I may leave out a detail or two to keep us focused on the fundamentals, but as you'll discover my hope is to share as much as possible. We'll focus primarily on the Claims authentication stack provided by <a href="http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&amp;id=17331">Windows Identity Foundation (WIF),</a> especially as it is extended and applied in SharePoint.</p>
<p>The foundation of the Claims authentication process in WIF and other authentication stacks is a number of standards and specifications managed by the Organization for the Advancement of Structured Information Standards (<a href="http://www.oasis-open.org/">OASIS</a>). These include the following:</p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 273px;" /><col style="width: 525px;" /></colgroup>
<tbody valign="top">
<tr style="background: #4f81bd;">
<td style="padding-left: 9px; padding-right: 9px; border-top: solid #4f81bd 1.0pt; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><span style="color: white;"><strong>Protocol</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p><span style="color: white;"><strong>Description</strong></span></p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss">WS-Security</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Defines a <strong>security token </strong>and how to include and/or refer to one in a SOAP message.</p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://docs.oasis-open.org/ws-sx/ws-trust/v1.4/ws-trust.html">WS-Trust</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Defines a <strong>Security Token Service</strong> and how to directly request a security token from such a service.</p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Among other things, specifies a profile for sending and receiving WS-Trust messages via a <strong>passive client</strong> (i.e. a web browser).</p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://docs.oasis-open.org/ws-sx/ws-secureconversation/v1.4/ws-secureconversation.html">WS-SecureConversation</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Defines the <strong>Security Context Security Token</strong> (SCT) used for maintaining a single authenticated context across multiple messages.</p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://www.oasis-open.org/standards#samlv1.1">Security Assertion Markup Language (SAML)</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Defines an XML schema for listing a subject and associated attributes. An assertion based on this schema is a <a href="http://www.oasis-open.org/committees/download.php/16768/wss-v1.1-spec-os-SAMLTokenProfile.pdf"><strong>SAML security token</strong></a>.</p>
</td>
</tr>
<tr>
<td style="padding-left: 9px; padding-right: 9px; border-left: solid #4f81bd 1.0pt; border-bottom: solid #4f81bd 1.0pt;">
<p><a href="http://www.oasis-open.org/standards#samlv2.0">SAML Protocol (SAMLP)</a></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-bottom: solid #4f81bd 1.0pt; border-right: solid #4f81bd 1.0pt;">
<p>Defines message patterns for requesting and receiving security tokens (e.g. SAML tokens) from a Security Token Service. Compare to WS-Trust and WS-Federation.</p>
</td>
</tr>
</tbody>
</table>
</div>
<h1>WS-Security: Security Tokens</h1>
<p>All of these standards are based on the concept of a security token, defined in WS-Security as follows:</p>
<blockquote>
<p>A <em>security token</em> represents a collection (one or more) of claims. (<a href="http://www.oasis-open.org/committees/download.php/16790/wss-v1.1-spec-os-SOAPMessageSecurity.pdf">WSS: SOAP Message Security</a>, Page 11, Line 326)</p>
</blockquote>
<p>Well-known types of security tokens include <a href="http://www.oasis-open.org/committees/download.php/16785/wss-v1.1-spec-os-x509TokenProfile.pdf">X.509 certificates</a>, <a href="http://www.oasis-open.org/committees/download.php/16788/wss-v1.1-spec-os-KerberosTokenProfile.pdf">Kerberos tickets</a>, <a href="http://www.oasis-open.org/committees/download.php/16768/wss-v1.1-spec-os-SAMLTokenProfile.pdf">SAML tokens</a>, and, yes, <a href="http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf">Username/Password tokens</a>. The claims asserted in a security token can include subjects, attributes (e.g. email addresses, names, and identifiers), symmetric and asymmetric (public) keys, passwords, and more. These claims often form the basis for authentication and authorization decisions, and may also be utilized to populate profiles or sign other tokens and messages.</p>
<p>Let's take an X.509 certificate token as an example. It specifies claims including the name of an entity and a public key associated with that entity. If a receiver of the X.509 token trusts this information, it can utilize the public key to verify that other messages signed by the associated private key truly originated from the associated entity. In addition, X.509 certificates are signed by another security token; this signature represents another claim asserted by the signing X.509 certificate that the entity in the signed certificate is the proper owner of the included public key.</p>
<p>To be useful, tokens received from a third party are almost always signed. The WS-Security spec defines a signed token as follows:</p>
<blockquote>
<p>A <em>signed security token</em> is a security token that is asserted and cryptographically signed by a specific authority (e.g. an X.509 certificate or a Kerberos ticket). (<a href="http://www.oasis-open.org/committees/download.php/16790/wss-v1.1-spec-os-SOAPMessageSecurity.pdf">WSS: SOAP Message Security</a>, Page 12, Line 330)</p>
</blockquote>
<p>However, just because a token has been signed by its issuer doesn't mean that the party presenting it to some other application is the proper owner and user of the token. For example, it could have been stolen in transit. To help confirm that the bearer of a token is in fact the proper owner of that token, some tokens, such as X.509 certificates and Kerberos tickets, associate the owner with a security key known only to that owner (e.g. a private key). This allows receivers to guarantee that messages signed by the specified private key originate from the proper owner of the token by checking that these messages have been signed by the associated key.</p>
<p>On the other hands, some tokens, notably SAML bearer tokens, don't rely on the bearer possessing a key; proof of ownership is demonstrated simply through possession. This is similar to cookie-based authentication, where the possessor of the cookie is assumed to be its rightful owner. Of course, HTTPS or some other transport-level encryption is essential in guaranteeing that the token or cookie hasn't been stolen. The concept of a bearer token comes up a lot in current Claims authentication, so come back and reread these last couple paragraphs in the future if you need to.</p>
<p>In the Windows Identity Foundation, Security Tokens are created, read, and validated by <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.securitytokenhandler.aspx">SecurityTokenHandler</a>s. Pre-programmed handlers available out-of-the-box include a <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.kerberossecuritytokenhandler.aspx">Kerberos handler</a>, a <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml11.saml11securitytokenhandler.aspx">SAML1.1 handler</a>, a <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml2.saml2securitytokenhandler.aspx">SAML2 handler</a>, and a <a href="http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.x509securitytokenhandler.aspx">X509 handler</a>, among <a href="http://msdn.microsoft.com/en-us/library/derivedtypelist_t_microsoft_identitymodel_tokens_securitytokenhandler.aspx">others</a>. SharePoint only supports handling <strong>SAML1.1 tokens</strong> directly.</p>
<h1>WS-Trust: Requesting and Receiving Security Tokens</h1>
<p>Having defined a security token, we now proceed to define how one goes about acquiring one. In some cases, such as X.509 certificates and Kerberos tickets, the token is acquired via "legacy" protocols such as via a Kerberos Ticket Granting Service or a X.509 Certificate Authority. For newer token formats such as SAML tokens, WS-Trust provides a protocol for requesting and receiving a token. In WS-Trust, the requestor sends a RequestSecurityToken (RST) request to a Security Token Service (STS) asking that STS to issue a security token asserting specified claims. Once the STS has satisfied itself that the requestor is entitled to the requested claims, it responds with a RequestSecurityTokenResponse (RSTR) containing the requested security token and any associated keys needed to use it.</p>
<p>For example, an entity with a Windows identity may request a SAML token specifying their UPN and information about AD groups they are part of. The requesting entity would craft an RST specifying the desired claims. It would then create a SOAP message including the RST in the body and a Kerberos ticket token in the header (to prove its rights to these claims) and submit this message to an STS. The STS would verify the Kerberos token and then create a SAML token with the requested claims. It would place the SAML token in an RSTR and place the RSTR in a SOAP message, which it would then send back to the requesting entity. The requesting entity would extract the new SAML security token from the message and use it as needed.</p>
<p>The Security Token Service provided with WIF and the STS implemented by SharePoint as the Security Token Service Application are both WS-Trust STS's. That is, they expect and process RSTs submitted directly in SOAP-based Issue requests, and send RSTRs back to the requestors in SOAP messages. (Note: the WIF STS can also act as a WS-Federation endpoint; more on that soon.)</p>
<p>Another common protocol for requesting and receiving security tokens is SAMLP (SAML Protocol). Although SAMLP is part of the SAML2 specification, you should be careful not to confuse SAML tokens with the SAML protocol. SAML tokens are XML security tokens asserting a collection of claims. The SAML protocol (SAMLP) is a protocol for requesting SAML (or other) security tokens. Currently, WIF and SharePoint do not support SAMLP, although ADFS does.</p>
<p>By understanding WS-Security and WS-Trust we've come a long way, but one element remains to be explained. The WS-Trust protocol just described works well in scenarios where an entity knows how to actively request and process a security token. This is fine for service-to-service communication, where the requesting service can be programmed to do just that. Web browsers, however, do not know how to craft RSTs and process RSTRs and security tokens. So another layer is needed to define how to request and utilize security tokens in end-user web applications (e.g. SharePoint). This brings us to&hellip;</p>
<h1>WS-Federation: Web Browsers (i.e. Passive Requestors)</h1>
<p>WS-Federation, specifically Section 13, contains a profile describing how to utilize the WS-Trust request/response protocol via a web browser, also referred to as a "passive" requestor. The simplest form of the process is illustrated in the following image from the spec:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/6735.WSFed_PassiveRequestorProfile_Simple.gif" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/6735.WSFed_5F00_PassiveRequestorProfile_5F00_Simple.gif"><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/67/6735.WSFed_PassiveRequestorProfile_Simple.gif" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-67/6735.WSFed_5F00_PassiveRequestorProfile_5F00_Simple.gif" width="388" height="400" /></a></p>
<p>(<a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.pdf">Web Services Federation Language v1.2</a>, page 95, Line 3173)</p>
</blockquote>
<p>When the browser requests a resource (e.g. a web page) without the required token (1), the web application (also known as a Relying Party, or RP) redirects the browser to an STS to get the needed token. It does this by replying to the request with a 302 Redirect response specifying the address of the STS endpoint to which the client should connect (2). The web application appends details about the token needed by adding a query string to this redirect URL. The web browser follows the redirect and sends the URL with query parameters to the STS endpoint (3). The endpoint authenticates the end-user (without going into details, this could be via a Kerberos ticket or a username/password combination) (4) and then prepares a RSTR to send back to the original web page. Here again, the browser cannot handle the RSTR on its own. Instead, the STS needs to redirect the browser with the appropriate RSTR back to the original web page (5). A 302 Redirect isn't enough in this case, as 302s can only perform GET requests to the destination URL and an RSTR is often too big to fit in a query string. A POST request to the original RP is initiated by setting some script in the response at step 5 that posts the RSTR to the original web page via the browser (6).</p>
<p>If all goes well, at this point the original web application will have an RSTR from the STS. It (the web application) can extract the security token from the RSTR and use it to authenticate the user and send back the requested resource (7).</p>
<h2>Following along with the passive requestor profile</h2>
<p>To help clarify this, let's follow the process when I access the management page for a namespace of mine in Windows Azure Active Directory (Azure Access Control Service). The management page is at https://joshgav.accesscontrol.windows.net/v2/mgmt/web. When I browse to this address in Internet Explorer I receive the following response:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 9pt;">HTTP/1.1 302 Found<br />Location: https://joshgav.accesscontrol.windows.net/v2/wsfederation?<strong>wa</strong>=wsignin1.0&amp;<strong>wtrealm</strong>=https%3a%2f%2fjoshgav.accesscontrol.windows.net%2fv2%2fmgmt%2fservice&amp;<strong>wreply</strong>=https%3a%2f%2fjoshgav.accesscontrol.windows.net%3a443%2fv2%2fmgmt%2fweb%2fsignin&amp;<strong>wctx</strong>=%2fv2%2fmgmt%2fweb </span></p>
<p>I've highlighted the query parameter keys to make it somewhat easier to identify them. These parameters are all defined in the WS-Federation spec. <strong>wa</strong> stands for the Action requested; <em>wsignin1.0</em> and <em>wsignout1.0</em> are the two most common actions and represent sign-in and sign-out requests respectively. <strong>wtrealm</strong> stands for Trusting Realm and designates the security realm which the requested security token is intended for. <strong>wreply</strong> specifies where the user should be sent back to with the received RSTR. Note that most of the time this reply address is the same or a child of the Trust Realm (wtrealm) (and often only or the other is specified). <strong>wctx</strong> is an optional parameter for specifying context to be retained and replayed back to the original page in the reply.</p>
<p>The URL I'm being redirected to (https://joshgav.accesscontrol.windows.net/v2/wsfederation) is the endpoint for the WS-Federation passive STS endpoint for my own ACS domain. ACS, WIF, and ADFS can all provide a WS-Federation STS endpoint. This STS is now responsible for authenticating me and ultimately sending me back to the URL and page I originally requested. It could authenticate me with a simple name and password or numerous other options which we won't get into right now. Once I'm authenticated, it sends me back a page with the requested RSTR embedded in a form along with some JavaScript directing my browser to post this form back to the original URL. The returned page looks like this:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 9pt;">&lt;html&gt;<br />&nbsp;&nbsp;&lt;head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;title&gt;Working...&lt;/title&gt;<br />&nbsp; &lt;/head&gt;<br />&nbsp; &lt;body&gt;<br />&nbsp;&nbsp;&nbsp; &lt;form method="POST" name="hiddenform" action="https://joshgav.accesscontrol.windows.net/v2/mgmt/web/signin"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="hidden" name="wa" value="wsignin1.0" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="hidden" name="wresult" value="<strong><em>HTML-encoded RSTR goes here (decoded below)</em></strong>" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="hidden" name="wctx" value="/v2/mgmt/web" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;noscript&gt;&lt;p&gt;Script is disabled. Click Submit to continue.&lt;/p&gt;&lt;input type="submit" value="Submit" /&gt;&lt;/noscript&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/form&gt;<br />&nbsp;&nbsp;&nbsp; &lt;script language="javascript"&gt;window.setTimeout('document.forms[0].submit()', 0);&lt;/script&gt;<br />&nbsp; &lt;/body&gt;<br />&lt;/html&gt; </span></p>
<p>The RSTR goes where I've indicated in bold. If you'd like to see what an RSTR looks like, I decoded and included it below. Note that ACS uses a Simple Web Token (SWT) security token and not a SAML token; we won't worry about that right now. I took the liberty of converting the SWT from Base64 and URL decoding it so you'd have the pleasure of seeing what it actually contains. This is a bearer token, by the way. If it was still valid (and I hadn't modified the <a href="http://tools.ietf.org/html/rfc2104">HMAC</a>), you could take it right out of this blog post and authenticate to my management service with it.</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 9pt;">&lt;t:RequestSecurityTokenResponse Context="/v2/mgmt/web" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"&gt;<br />&nbsp;&nbsp;&lt;t:Lifetime&gt;<br />&nbsp;&nbsp;&nbsp; &lt;wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;2012-04-25T20:07:47.376Z&lt;/wsu:Created&gt;<br />&nbsp;&nbsp;&nbsp; &lt;wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;2012-04-26T04:07:47.376Z&lt;/wsu:Expires&gt;<br />&nbsp; &lt;/t:Lifetime&gt;<br />&nbsp; &lt;wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"&gt;<br />&nbsp;&nbsp;&nbsp; &lt;EndpointReference xmlns="http://www.w3.org/2005/08/addressing"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Address&gt;https://joshgav.accesscontrol.windows.net/v2/mgmt/service&lt;/Address&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/EndpointReference&gt;<br />&nbsp; &lt;/wsp:AppliesTo&gt;<br />&nbsp; &lt;t:RequestedSecurityToken&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;wsse:BinarySecurityToken<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wsu:Id="uuid:73344c18-47a2-40d7-9ea7-1b63a8eb182c"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueType="http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" &gt;<br /><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://schemas.microsoft.com/ws/2008/06/identity/claims/role=Administrator<br /></em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>&amp;http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider=uri:WindowsLiveID<br /></em><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;Audience=https://joshgav.accesscontrol.windows.net/v2/mgmt/service<br /></em><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;ExpiresOn=1336035077&amp;Issuer=https://joshgav.accesscontrol.windows.net/<br /></em><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;HMACSHA256=e3JilQ6AHWCH5FtSwqXxEEgQ6mUF6gOa1PvoyAi65fI=<br /></em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/wsse:BinarySecurityToken&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/t:RequestedSecurityToken&gt;<br />&nbsp; &lt;t:TokenType&gt;http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0&lt;/t:TokenType&gt;<br />&nbsp; &lt;t:RequestType&gt;http://schemas.xmlsoap.org/ws/2005/02/trust/Issue&lt;/t:RequestType&gt;<br />&nbsp; &lt;t:KeyType&gt;http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&lt;/t:KeyType&gt;<br />&lt;/t:RequestSecurityTokenResponse&gt; </span></p>
<p>Once this form with its keys and values is posted back to the original requested URL (the ACS management page), the web application extracts the presented token, checks my authorization for the page requested and (if I'm authorized) serves me said page. In the case of the ACS Management service and most web apps, a cookie is set at this point so that the token won't need to be requested and/or processed for each subsequent request.</p>
<h1>Conclusion</h1>
<p>At this point we've covered the WS-Security, WS-Trust, and WS-Federation protocols. We've touched on SAML and other token profiles such as Kerberos, X.509, and even SWT. There's still quite a long ways to go in explaining how WIF automates and coordinates all of these elements for you, but with these foundations you'll find the ensuing conversations easier to follow.</p>]]></content:encoded>
    </item>
    <item>
      <title>Better SharePoint Lists and List Items in PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/besidethepoint/better-sharepoint-lists-and-list-items-in-powershell</link>
      <pubDate>Wed, 08 Feb 2012 14:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Josh Gavant [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/besidethepoint/2012/02/08/better-sharepoint-lists-and-list-items-in-powershell/</guid>
      <description><![CDATA[Those who've read some of my previous articles or attended my PowerShell trainings know how much...]]></description>
      <content:encoded><![CDATA[<p>Those who've read some of my previous articles or attended my PowerShell trainings know how much emphasis I put on PowerShell's object-centric nature. The great power of PowerShell lies in its ability to dynamically create objects and members from many different object frameworks, including .NET, COM, WMI, XML, and ADO.NET data sources. SharePoint lists are another example of a data source which would be nice to be able to treat as a collection of objects in PowerShell. While there are some good options for working with SharePoint list items as objects in C# such as LINQ to SharePoint and ADO.NET Data Services, these options are not readily available in PowerShell.</p>
<p>In this post, we'll discuss the information returned by SPList and SPListItem objects and a way to retrieve the actual columns and values stored in a SharePoint list as first-class properties of PowerShell objects. To assist with this you can utilize the SPList module attached to this post. Store the module folder in one of the paths in the $env:PSModulePath variable (e.g. \windows\system32\WindowsPowerShell\v1.0\Modules) and run the following on a SharePoint server to get started:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; Import-Module SPList </span></p>
<p>To begin, let us discuss how to access information about lists via PowerShell. In the SharePoint hierarchy, the final level for which an out-of-the-box cmdlet exists is the SPWeb object. SPWeb objects represent individual sites in a site collection and contain lists and folders. The simplest way to retrieve all lists in a SharePoint site is as follows (of course, change the value for $SiteUrl to a URL in your farm):</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $SiteUrl = "http://sharepoint10"<br />PS:&gt; $web = Get-SPWeb $SiteUrl<br />PS:&gt; $web.Lists | Sort-Object -Property Title | Format-Table -Property Title </span></p>
<p>No default formatting is defined for SPList objects, so if you don't specify a little formatting via the Format-Table command (as above) or a custom format.ps1xml file you'll end up with way too much information scrolling down your screen. The module included with this post includes a format.ps1xml file which causes SPList objects to be returned as a nicely formatted table or list by default.</p>
<p>If you like, the module available with this post includes a Get-SPList function. The function requires a list name and a SPWeb reference. The SPWeb reference can be an actual URL or can be taken from the pipeline. Two usage examples for the Get-SPList function follow:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $SiteUrl = "http://sharepoint10"<br />PS:&gt; Get-SPList -ListName *Announce* -Web $SiteUrl<br />PS:&gt; Get-SPSite -Identity $SiteUrl | Get-SPWeb | Get-SPList *announce* </span></p>
<p>The latter example will retrieve all lists with the letters "announce" in their title in all sites (webs) in the specified site collection. Try it!</p>
<p>Once you have a list you can retrieve the items available in that list. Doing so with the object model would look like this:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $ListName = "Announcements"<br />PS:&gt; $List = $web.Lists[$ListName]<br />PS:&gt; $List.Items | Format-Table -Property Title, ID </span></p>
<p>Again, by default the formatting isn't particularly pretty so we fix it up with Format-Table. And again, the module included with this post includes some prettier formatting instructions for SPListItem objects.</p>
<p>Compare the output of properties and values returned for a list item in PowerShell with the actual column names and values in the SharePoint list (for example in the Web UI). You'll discover that the information returned in PowerShell (from the object model) is actually only metadata about the list item, not the actual list item column names and values themselves. We'll shortly introduce a function which will retrieve the actual data for each SharePoint list item, but first let's see how you'd accomplish this via the object model itself.</p>
<p>First, you generally have to know the name of the column you're looking for in advance. We'll use the Body column in the Announcements list. To retrieve the values for the Title and Body fields for these list items, do this:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $List.Items | Format-Table -Property Title, @{Label="Body";Expression={$_["Body"]}} </span></p>
<p>Not pretty is it? Notice how we have to use index notation and hardcode the name of the column we want to retrieve. This is brittle - for example if the list item happened to not have a "Body" column we'd likely get an error. We also have little ability to pipe these results down the pipeline for further evaluation and filtering. For these reasons I've written a function called Get-SPListItem which returns an object whose members (properties) represent the actual column names in the SharePoint list and their respective values for each list item. It's part of the module included with this post and usage looks like this:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $WebUrl = "http://sharepoint10"<br />PS:&gt; Get-SPList -ListName Announcements -Web $WebUrl | Get-SPListItem </span></p>
<p>That's it! The objects it returns contain a property BaseListItem which refers to the original list item (with object metadata) and then a variable number of dynamic properties which reflect the actual data stored on the list item. The way it works is by scanning the list of fields associated with each list item via that item's Fields property and then creating a dynamic property named after the field and with the value stored on the item for that field. Because it looks at the Fields property for each list item it works even on Lists that contain multiple content types (and hence different Fields collections for each list item).</p>
<p>If you need the metadata directly for a list item and want to use the function, I've included an "-OriginalOnly" switch which will return the original SPListItem object.</p>
<p>One of my original uses for these functions was to help in reviewing the "Review Problems and Solutions" list generated by the Health Analyzer after its checks. Items get added to this list and are assigned a HealthReportSeverity of 0-4, with 0 representing a critical error, 1 an error, 2 a warning, and 4 success. Using the functions in the SPList module you can automatically retrieve latest results and even filter by severity. Based on what you find, sending an email message or otherwise tripping some sort of alarm shouldn't be too difficult. Following are some genericized examples which should help you get started in any environment:</p>
<p style="background: #e5e5e5;"><span style="font-family: Consolas; font-size: 10pt;">PS:&gt; $CAWebApp = Get-SPWebApplication -IncludeCentralAdministration | ? {$_ -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication] }<br />PS:&gt; $CAWeb = Get-SPSite -WebApplication $CAWebApp | Get-SPWeb | ? {$_.Title -eq "Central Administration"}<br />PS:&gt; Get-SPList -Web $CAWeb -ListName "Review Problems and Solutions"<br />PS:&gt; Get-SPList -Web $CAWeb -ListName "Review Problems and Solutions" | Get-SPListItem<br />PS:&gt; Get-SPList -Web $CAWeb -ListName "Review Problems and Solutions" | Get-SPListItem | Format-List *Health*<br />PS:&gt; Get-SPList -Web $CAWeb -ListName "Review Problems and Solutions" | Get-SPListItem | ? {$_.HealthReportSeverity -match "^[012]"} | Format-List *Health* </span></p>
<p>With this background you're close to being&nbsp;able to <em>set</em> properties on lists and list items as well. For guidance, check out <a title="this post" href="http://blogs.msdn.com/b/kaevans/archive/2012/01/24/creating-sharepoint-folders-and-items-with-powershell.aspx" target="_blank">this post</a> by fellow PFE Kirk Evans.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/26/56/35/SPList.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-26-56-35/SPList.zip">SPList.zip</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>