Just to remind myself, the list of claim types and their encodings are listed here at the bottom.
http://msdn.microsoft.com/en-us/library/gg481769.aspx
Where for example:
i:0#.w|contoso\scicoria
‘i’ = identity, could be ‘c’ for others
# == SPClaimTypes.UserLogonName
. == Microsoft.IdentityModel.Claims.ClaimValueTypes.String
Table for reference:
Table 1. Claim types encoding
!
SPClaimTypes.IdentityProvider
”
SPClaimTypes.UserIdentifier
#
SPClaimTypes.UserLogonName
$
SPClaimTypes.DistributionListClaimType
%
SPClaimTypes.FarmId
&
SPClaimTypes.ProcessIdentitySID
‘
SPClaimTypes.ProcessIdentityLogonName
(
SPClaimTypes.IsAuthenticated
)
Microsoft.IdentityModel.Claims.ClaimTypes.PrimarySid
*
Microsoft.IdentityModel.Claims.ClaimTypes.PrimaryGroupSid
+
Microsoft.IdentityModel.Claims.ClaimTypes.GroupSid
-
Microsoft.IdentityModel.Claims.ClaimTypes.Role
.
System.IdentityModel.Claims.ClaimTypes.Anonymous
/
System.IdentityModel.Claims.ClaimTypes.Authentication
0
System.IdentityModel.Claims.ClaimTypes.AuthorizationDecision
1
System.IdentityModel.Claims.ClaimTypes.Country
2
System.IdentityModel.Claims.ClaimTypes.DateOfBirth
3
System.IdentityModel.Claims.ClaimTypes.DenyOnlySid
4
System.IdentityModel.Claims.ClaimTypes.Dns
5
System.IdentityModel.Claims.ClaimTypes.Email
6
System.IdentityModel.Claims.ClaimTypes.Gender
7
System.IdentityModel.Claims.ClaimTypes.GivenName
8
System.IdentityModel.Claims.ClaimTypes.Hash
9
System.IdentityModel.Claims.ClaimTypes.HomePhone
<
System.IdentityModel.Claims.ClaimTypes.Locality
=
System.IdentityModel.Claims.ClaimTypes.MobilePhone
>
System.IdentityModel.Claims.ClaimTypes.Name
?
System.IdentityModel.Claims.ClaimTypes.NameIdentifier
@
System.IdentityModel.Claims.ClaimTypes.OtherPhone
[
System.IdentityModel.Claims.ClaimTypes.PostalCode
\
System.IdentityModel.Claims.ClaimTypes.PPID
]
System.IdentityModel.Claims.ClaimTypes.Rsa
^
System.IdentityModel.Claims.ClaimTypes.Sid
_
System.IdentityModel.Claims.ClaimTypes.Spn
`
System.IdentityModel.Claims.ClaimTypes.StateOrProvince
a
System.IdentityModel.Claims.ClaimTypes.StreetAddress
b
System.IdentityModel.Claims.ClaimTypes.Surname
c
System.IdentityModel.Claims.ClaimTypes.System
d
System.IdentityModel.Claims.ClaimTypes.Thumbprint
e
System.IdentityModel.Claims.ClaimTypes.Upn
f
System.IdentityModel.Claims.ClaimTypes.Uri
g
System.IdentityModel.Claims.ClaimTypes.Webpage
Character
Claim Type
Microsoft.IdentityModel.Claims.ClaimValueTypes.Base64Binary
“
Microsoft.IdentityModel.Claims.ClaimValueTypes.Boolean
Microsoft.IdentityModel.Claims.ClaimValueTypes.Date
Microsoft.IdentityModel.Claims.ClaimValueTypes.Datetime
Microsoft.IdentityModel.Claims.ClaimValueTypes.DaytimeDuration
Microsoft.IdentityModel.Claims.ClaimValueTypes.Double
Microsoft.IdentityModel.Claims.ClaimValueTypes.DsaKeyValue
Microsoft.IdentityModel.Claims.ClaimValueTypes.HexBinary
Microsoft.IdentityModel.Claims.ClaimValueTypes.Integer
Microsoft.IdentityModel.Claims.ClaimValueTypes.KeyInfo
Microsoft.IdentityModel.Claims.ClaimValueTypes.Rfc822Name
Microsoft.IdentityModel.Claims.ClaimValueTypes.RsaKeyValue
Microsoft.IdentityModel.Claims.ClaimValueTypes.String
Microsoft.IdentityModel.Claims.ClaimValueTypes.Time
Microsoft.IdentityModel.Claims.ClaimValueTypes.X500Name
Microsoft.IdentityModel.Claims.ClaimValueTypes.YearMonthDuration
Be nice to be able to make wildcard certificates for use in development with makecert – turns out, it’s real easy. Just ensure that your CN= is the wildcard string to use.
The following sequence generates a CA cert, then the public/private key pair for a wildcard certificate
REM make the CA rem CA Certificate: makecert -r -pe -n "CN=AA Contoso Test Root Authority" -ss CA -sr CurrentUser -a sha1 -sky signature -cy authority -sv CA.pvk CA.cer -len 2048 REM now make the server wildcard cert makecert -pe -n "CN=*.contosotest.com" -a sha1 -len 2048 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -ic CA.cer -iv CA.pvk -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -sv wildcard.pvk wildcard.cer pvk2pfx -pvk wildcard.pvk -spc wildcard.cer -pfx wildcard.pfx
Well, apparently I missed this hidden feature having used the Lorem Ipsum website for some time, but if you enter the following in blank Word document – you’ll get 10 paragraphs of generated text:
=Lorem(10)
Such as:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.
Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.
Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.
Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.
Fusce aliquet pede non pede. Suspendisse dapibus lorem pellentesque magna. Integer nulla.
Donec blandit feugiat ligula. Donec hendrerit, felis et imperdiet euismod, purus ipsum pretium metus, in lacinia nulla nisl eget sapien. Donec ut est in lectus consequat consequat.
Etiam eget dui. Aliquam erat volutpat. Sed at lorem in nunc porta tristique.
Proin nec augue. Quisque aliquam tempor magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Nunc ac magna. Maecenas odio dolor, vulputate vel, auctor ac, accumsan id, felis. Pellentesque cursus sagittis felis.
The approach takes advantage of the SP 2010 OOB Session Token handler and FBA claims provider implementation that during a period of token lifetime, if there is activity during the period of time that can be defined as "EW" in the image in the section "Background" below, that the SPSecurityTokenManager will, with the FBA provider, reissue a Session Token with new SessionToken ValidTo and ValidFrom times without forcing a re-challenge for user credentials (username and password).
Additionally, it takes advantage of the ability to provide an event handler, on the SessionAuthentcationModule (SPSessionAuthenticationModule) to cause a reissue of the token temporarily with an expiry time (ValidTo) that will cause a SPSessionToken cache miss – thus forcing the re-issue by the SPSecurityTokenManager.
General Approach
The following is a contrived example and uses a rudimentary approach for determine how/when to indicate that the token should be "refreshed" This is done by hooking into the WIF Session Authentication Module's (SAM) Event "SessionSecurityTokenReceived".
The approach taken, and shown on the internet in several posts is to subclass the HttpApplication implementation.
The approach I recommend is to leverage the ability of any HttpApplication by ways of built in ability to identify all HttpModules loaded for that ASP.NET application (SP included) and determine if there are Event handlers specified by ways of the Global.asax in the Root of the SP IIS Site. This is handled by the System.Web.HttpApplication.HookupEventHandlersForApplicationAndModules method.
Note: There are alternatives that I've also tested that work – 1 approach is to register a new HttpModule, then in that HttpModule is to register "1" time a handler for the SAM's SessionSecurityTokenReceived event. This requires a method of indicating at the application level that a handler has already been registered.
Scenario Supported
The general scenario is:
DateTime newValidTo = DateTime.UtcNow.Add(logonWindow);
Sample Code for Event Handler
The sample code uses another class to contain the code; your implementation could just as easily keep this in the global.asax – however, I'm of the belief that the global.asax should be kept as pristine as possible.
The following code is placed in an assembly that is resolvable through normal fusion – that is, it could be a private assembly. I've chosen GAC in the sample project just for the ease of development.
The code below handles the event and just looks for a page (Url) that contains a well-known request string. This could be anything, but ensure that it's not a common page and based upon the application needs, how your logic will determine a need to refresh all claims.
<%@ Assembly Name="Microsoft.SharePoint" %> <%@ Assembly Name="RefreshClaimsSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=329ca2a6e4eeb8c6" %> <%@ Application Language="C#" Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" %> <%@ Import Namespace="Microsoft.IdentityModel.Web" %> <%@ Import Namespace="Microsoft.IdentityModel.Tokens" %> <%@ Import Namespace="Microsoft.SharePoint.IdentityModel" %> <script runat="server"> void SessionAuthentication_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e) { RefreshClaimsSample.SampleRefreshClaims.ForceRefreshClaims(sender, e); } </script>
public static void ForceRefreshClaims(object sender, SessionSecurityTokenReceivedEventArgs e) { if (HttpContext.Current.Request.Url.AbsoluteUri.Contains("RefreshClaims.aspx")) { SessionAuthenticationModule sam = sender as SessionAuthenticationModule; var logonWindow = SPSecurityTokenServiceManager.Local.LogonTokenCacheExpirationWindow; DateTime newValidTo = DateTime.UtcNow.Add(logonWindow); e.SessionToken = sam.CreateSessionSecurityToken( e.SessionToken.ClaimsPrincipal, e.SessionToken.Context, e.SessionToken.ValidFrom, newValidTo, e.SessionToken.IsPersistent); e.ReissueCookie = true; } }
Wiring up Event Handler
In the SP Global.asax provided a method signature that matches the event from the SAM.
The requirements are that the signature is as follows:
void <moduleNameFromConfig>_<eventName> ( eventArgsType )
Where:
Background
In the above diagram, the settings:
These settings are obtained and modified via PowerShell under the SPSecurityT0kenServiceConfig set of cmdlets.
For the following samples, assume the following:
TL – EW = 6 Minutes
Solution Zip
This is to provide a little bit of explanation on the implementation of FBA authentication with SP 2010. There have been blog posts that indicate there are no sliding sessions, but with a little manipulation and understanding of some of the settings, there is somewhat of support for sliding sessions and re-issuance of tokens. The current model provides for a little trade-off on performance as re-requests to the FBA providers and also any SP Custom Claim providers can have impact on overall performance.
The following diagram represents the initial static view of the SP 2010 Security Token Service Configuration settings that control the management of Tokens issued under Forms Based Authentication (FBA) authentication.
The current SP 2010 April 2011 CU’s does support a level of sliding sessions as long as a request (user activity) occurs in the window of time after token issuance (logon or re-issuance) defined in the “EW” segment below.
Example 1:
Example 2:
Example 3:
Note in the above scenarios that the “(All Claims Providers Called)” indicates that the Claims Providers registered for the Web Application / Site are then called; any custom SPClaimProvider implementations will have the method FillClaimsForEntity called at that time
There are really 2 ways to get a SPClaimProvider registered – 1 via a Farm Feature activation. The other is via PowerShell.
However, the documentation on how to remove is not that clear.
The following code will remove it based upon a TypeName. Other identifiers can be used.
In order to remove:
Get-SPClaimProvider | ForEach-Object { Write-Host $_.TypeName IF ( $_.TypeName -eq "SimpleClaimsProvider.LVClaimsProvider") { Write-Host "Found" $cp = $_ } } $cp.DisplayName Remove-SPClaimProvider $cp
If you’re writing a custom SharePoint Claims Provider (SPClaimProvider) in order to augment claims, it’s important to also understand what process is executing your specific code path. In the situation where you are making calls to a DB or service endpoint you will need to understand which process actually makes that call.
In situations when running in a Trusted Subsystem model, you’ll also need to RunWithElevated in order to have that code path execute in the context of the Windows Principal for that process.
The following table illustrates for the abstract members of the SPClaimProvider class when implemented and where they execute:
Method / Property
Web App
FillClaimTypes
X
FillClaimValueTypes
FillClaimsForEntity
FillEntityTypes
FillHierarchy
FillResolve
FillSchema
FillSearch
Name
SupportsEntityInformation
SupportsHierarchy
SupportsResolve
SupportsSearch
So, if you have your persistence in a SQL DB, and your using Windows Authentication (and using RunWithElevated) you’ll need to grant (or have) to the appropriate SQL permissions; generally, I’ve just granted “datareader”.
This seems to come up a few times. The following sample script in PS applies a common master page across all SPWebs in a site collection.
$site = Get-SPSite http://fba.contosotest.com/dv1 $site | Get-SPWeb -limit all | ForEach-Object { $_.MasterUrl = "/dv1/_catalogs/masterpage/custom_v4.master";$_.Update() } $site.Dispose()
Thanks to Phil Childs - http://get-spscripts.com/2010/09/changing-master-page-on-sharepoint.html