sharepoint saturday toronto july 2012 - antonio maio
DESCRIPTION
SharePoint Saturday Toronto - Antonio Maio July 2012 - Developing Custom Claim Providers for AuthorizationTRANSCRIPT
Developing Custom Claim Providers to Enable AuthorizationAntonio MaioMicrosoft SharePoint Server MVPTITUS Senior Product Manager
Email: [email protected]: www.trustsharepoint.comTwitter: @AntonioMaio2
SponsorsEnterprise
Standard
Agenda
IntroductionIn Brief: Claims in SharePoint 2010Getting the Right Claims for Authorization?Developing a Custom Claim ProviderClaims from Multiple SourcesExample Claim ProvidersDeployment and Final Considerations
Topic
Introduction
Antonio MaioMicrosoft SharePoint Server MVPTITUS Senior Product ManagerEmail: [email protected]: www.trustsharepoint.comTwitter: @AntonioMaio2
TITUS
Data Security & Classification Market LeaderOver 300 Enterprise CustomersOver 2 Million Users Deployed
SharePoint Security
Email and Document Marking
Information Protection Solutions
TopicIn Brief: Claims in SharePoint 2010
Claims in SharePoint 2010
Claims are trusted attributes about users
Claims can be assigned as permissionsWith a permission levelAssign to sites, libraries, folders, items, documents
SharePoint will authorize permissions on content based on claims
If user has a matching claim in their identity when they sign in, SharePoint will grant that level of access to contentBehave like domain groups
Available only in SharePoint 2010Only in claims authentication enabled web applications
TopicGetting the Right Claims into SharePoint for Authorization?
Authorization
Determining what resources users are permitted to access and what actions they’re permitted to perform
Typically through policies using information about the user, information about the resource, etc…
Using claims enhances Authorization to…Be specific to the userBe done without knowing who the user isBe dynamic – ex. changes in a user’s security clearanceInclude environmental attributes (current time, GEO location, connection type, etc.)Be an alternative to security groups – Groups do not scalePolicy Example: user must be part of GroupA and GroupB and GroupC to access a resources
What types of claims do we need?
Military, Intelligence, Government Defense
Security ClearanceCaveatNeed to Know
CommercialDepartment or TeamRoleCurrent Date/Time, Current Device (BYOD)Group Membership with multiple groups
Aerospace/Defense ContractingNationality + Current Location
Homeland SecurityAgency (law enforcement, emergency response, public health…)Scope or Level (local, state, federal)Current Threat Level
Options for Retrieving/Managing Claims
Trusted Identity Provider
SharePoint2010
Client SystemEx. web browser
Secure Token Server (STS)
EX. Active Directory Federation Services(ADFS version 2.0)
Database or Directory
Ex. Active Directory
3. Get info (claims)
about user
Token with Claims
Format: SAML/WS-Fed 4. Authenticates user & creates
token
1. User login(with username &
password)
2. Requests authentication & token
5. User is authenticated and SharePoint 2010 now has user’s
claims
Claim Rule
Claim Rule…
Custom Claim Provider
Custom Claim Provider…
SQL DB, LDAP, PKI
etc…
iAttributeStore …
Focus: Custom Claim Providers
SharePoint2010
Client SystemEx. web browser
Active Directory
1. User login(with username &
password)
Custom Claim Provider
Custom Claim Provider…
TopicDeveloping a Custom Claim Provider
Custom Claim Providers
SharePoint farm level feature
Can deploy more than one
Called after user is authenticated…and after Trusted Identity Provider has already returned claims
Built on top of WIF (Windows Identity Framework)Used to augment claimsUsed to transform claims
Building a Custom Claim Provider1. Add necessary References
Microsoft.SharePointMicrosoft.IdentityModel
Browse to find it in \Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5\Microsoft.IdentityModel.dll
2. Add necessary Using statements using System; using System.Xml; using System.IO; using System.ServiceModel.Channels; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; using Microsoft.SharePoint.Administration.Claims; using Microsoft.SharePoint.WebControls;
3. Add a Class which inherits from SPClaimProvidernamespace SampleClaimProvider {
public class ClearanceClaimProvider : SPClaimProvider { public ClearanceClaimProvider (string displayName) :
base(displayName) {
} }
}
Building a Custom Claim Provider4. Implement the Abstract
class
Methods:
FillClaimTypesFillClaimValueTypesFillClaimsForEntityFillEntityTypes
FillHierarchyFillResolve(2 overrides)FillSchemaFillSearch
Properties:NameSupportsEntityInformationSupportsHierarchySupportsResolveSupportsSearch
public class ClearanceClaimProvider:SPClaimProvider { }
Right click on SPClaimProvider and select…
Building a Custom Claim Provider5. Implement Required Properties
public override string Name{get { return ProviderInternalName; }}
public override bool SupportsEntityInformation{get { return true; }}
public override bool SupportsHierarchy{get { return true; }}
public override bool SupportsResolve{get { return true; }}
public override bool SupportsSearch{get { return true; }}
Must return True for Claims Augmentation
Returns the Claim Provider unique name
Supports hierarchy display in people picker
Supports resolving claim valuesSupports search operation
Building a Custom Claim Provider
6. Create Static Properties for Name
internal static string ProviderDisplayName {
get { return “Security Clearance"; } }
internal static string ProviderInternalName {
get { return “SecurityClearanceProvider"; } }
Building a Custom Claim Provider
7. Create Data Source and Helper Functions
private string[] SecurityLevels = new string[] { "None", "Confidential", "Secret", "Top Secret" };
private static string ClearanceClaimType{
get { return "http://schemas.sample.local/clearance"; }}
private static string ClearanceClaimValueType{
get { return Microsoft.IdentityModel.Claims.ClaimValueTypes.String;} }
• Adding a claim with type URL http://schemas.sample.local/clearance and the claim’s value is a string
Building a Custom Claim Provider
8. Implement Methods to Augment ClaimsFillClaimTypesFillClaimValueTypesFillClaimsForEntity
protected override void FillClaimTypes(List<string> claimTypes){
if (claimTypes == null)throw new ArgumentNullException("claimTypes");
claimTypes.Add(ClearanceClaimType); }
protected override void FillClaimValueTypes(List<string> claimValueTypes)
{ if (claimValueTypes == null)
throw new ArgumentNullException("claimValueTypes");
claimValueTypes.Add(ClearanceClaimValueType); }
The Action: Building a Custom Claim Provider
9. Implement FillClaimsForEntity to augment claims
protected override void FillClaimsForEntity(Uri context, SPClaim entity, List<SPClaim> claims)
{if (entity == null)
throw new ArgumentNullException("entity");if (claims == null)
throw new ArgumentNullException("claims");if (String.IsNullOrEmpty(entity.Value))
throw new ArgumentException("Argument null or empty", "entity.Value");
//if existing Clearance claim is ‘top secret’ then add lower levels clearancesif (. . .){
claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[0], ClearanceClaimValueType));
claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[1], ClearanceClaimValueType));
claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[2], ClearanceClaimValueType));
}. . .
}
Customizing the People Picker
FillEntityTypesSet of possible claims to display in the people picker
FillHierarchyHierarchy for displaying claims in the people picker
FillResolve(2 overrides)Resolving claims specified in the people picker
FillSchemaSpecifies the schema that is used by people picker to display claims/entity data
FillSearchFills in search results in people picker window
Other Important Methods: Replacing the People Picker
Using Claims for Authorization
You will assign claims as permissions either
Through People PickerProgrammatically through code
In both cases you must implementFillEntityTypesFillHierarchyFillResolve(2 overrides)FillSchemaFillSearch
…or the augmented claims will not be available to you
Using Claims for Authorization
FillEntityTypes protected override void FillEntityTypes(List<string> entityTypes)
{ //Return the type of entity claim we are using entityTypes.Add(SPClaimEntityTypes.FormsRole); }
Using Claims for Authorization
FillHierarchy protected override void FillHierarchy(Uri context, string[] entityTypes, string hierarchyNodeID, int numberOfLevels, SPProviderHierarchyTree hierarchy) { if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole)) return;
switch (hierarchyNodeID) { case null: // when it 1st loads, add all our nodes hierarchy.AddChild(new Microsoft.SharePoint.WebControls.SPProviderHierarchyNode (SecurityClearance.ProviderInternalName, “SecurityClearance”, “Security Clearance”, true));
break;
default: break; } }
hierarchy.AddChild(new Microsoft.SharePoint.WebControls.SPProviderHierarchyNode (SecurityClearance.ProviderInternalName, “Caveat”, “Caveat”, true));
Using Claims for Authorization
FillResolve (1st override) protected override void FillResolve(Uri context, string[] entityTypes, SPClaim resolveInput, List<PickerEntity> resolved) { if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole)) return;
Microsoft.SharePoint.WebControls.PickerEntity pe = GetPickerEntity (resolveInput.ClaimType, resolveInput.Value);
resolved.Add(pe); }
Using Claims for Authorization
FillResolve (2nd override) protected override void FillResolve(Uri context, string[] entityTypes, string resolveInput, List<PickerEntity> resolved) { if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole)) return;
//create a matching entity and add it to the return list of picker entries Microsoft.SharePoint.WebControls.PickerEntity pe = GetPickerEntity (ClearanceClaimType, resolveInput);
resolved.Add(pe);
}
pe = GetPickerEntity(CaveatClaimType, resolveInput);resolved.Add(pe);
Using Claims for Authorization
GetPickerEntity private Microsoft.SharePoint.WebControls.PickerEntity GetPickerEntity (string ClaimType, string ClaimValue) { Microsoft.SharePoint.WebControls.PickerEntity pe = CreatePickerEntity();
// set the claim associated with this match & tooltip displayed pe.Claim = CreateClaim(ClaimType, ClaimValue, ClaimValueType); pe.Description = SecurityClearance.ProviderDisplayName + ":" + ClaimValue;
// Set the text displayed in people picker pe.DisplayText = ClaimValue;
// Store in hash table, plug in as a role type entity & flag as resolved pe.EntityData[Microsoft.SharePoint.WebControls.PeopleEditorEntityDataKeys. DisplayName] = ClaimValue; pe.EntityType = SPClaimEntityTypes.FormsRole; pe.IsResolved = true;
pe.EntityGroupName = "Additional Claims"; return pe; }
Using Claims for Authorization
FillSchema protected override void FillSchema(SPProviderSchema schema) { schema.AddSchemaElement(new Microsoft.SharePoint.WebControls.SPSchemaElement( Microsoft.SharePoint.WebControls.PeopleEditorEntityDataKeys.DisplayName, "Display Name", Microsoft.SharePoint.WebControls.SPSchemaElementType.Both)); }
Using Claims for AuthorizationFillSearch
protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID,int maxCount, SPProviderHierarchyTree searchTree) { if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole)) return;
// The node where we will place our matches Microsoft.SharePoint.WebControls.SPProviderHierarchyNode matchNode = null;
Microsoft.SharePoint.WebControls.PickerEntity pe = GetPickerEntity (ClearanceClaimType, searchPattern);
if (!searchTree.HasChild(“SecurityClearance”)) { // create the node so that we can show our match in there too matchNode = new Microsoft.SharePoint.WebControls.SPProviderHierarchyNode (SecurityClearance.ProviderInternalName, “Security Clearance”, “SecurityClearance”, true); searchTree.AddChild(matchNode); } else { // get the node for this security level matchNode = searchTree.Children.Where(theNode => theNode.HierarchyNodeID == “SecurityClearance”).First(); }
// add the picker entity to our tree node matchNode.AddEntity(pe); }
Using Claims for AuthorizationFillSearch
protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID,int maxCount, SPProviderHierarchyTree searchTree) { if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole)) return;
// The node where we will place our matches Microsoft.SharePoint.WebControls.SPProviderHierarchyNode matchNode = null;
Microsoft.SharePoint.WebControls.PickerEntity pe = GetPickerEntity (ClearanceClaimType, searchPattern);
if (!searchTree.HasChild(“SecurityClearance”)) { // create the node so that we can show our match in there too matchNode = new Microsoft.SharePoint.WebControls.SPProviderHierarchyNode (SecurityClearance.ProviderInternalName, “Security Clearance”, “SecurityClearance”, true); searchTree.AddChild(matchNode); } else { // get the node for this security level matchNode = searchTree.Children.Where(theNode => theNode.HierarchyNodeID == “SecurityClearance”).First(); }
// add the picker entity to our tree node matchNode.AddEntity(pe); }
Replicate code block for each claim type
Topic
Claim Provider Examples
Claim Provider Examples
Example 1: Access sensitive information only during work hours
protected override void FillClaimsForEntity(Uri context, SPClaim entity, List<SPClaim> claims){
. . .
DateTime now = DateTime.Now;if((now.DayOfWeek == DayOfWeek.Saturday)||(now.DayOfWeek == DayOfWeek.Sunday)){ claims.Add(CreateClaim(WorkDayClaimType,”false”, WorkDayClaimValueType)); return;}
DateTime start = new DateTime(now.Year, now.Month, now.Day, 9, 0, 0)); //9 o'clock AMDateTime end = new DateTime(now.Year, now.Month, now.Day, 17, 0, 0)); //5 o'clock PM
if ((now < start) || (now > end)){ claims.Add(CreateClaim(WorkDayClaimType,”false”, WorkDayClaimValueType)); return;}
claims.Add(CreateClaim(WorkDayClaimType, ”true”, WorkDayClaimValueType));}
Claim Provider Examples
Example 2: Information Release Dates for Mergers and Acquisitions
Create a SharePoint list where release dates are registered for each acquisition – name it ‘Acquisition Release Register’
With each list item specify the acquisition project name and release date
To the document library holding acquisition documents add a ‘lookup’ metadata column pointing to ‘Acquisition Release Register’
With every document added user selects a release entry from the Acquisition Release RegisterUse 3rd party tools or code to add a claim to the item that matches the metadata column value
Custom claim provider uses SharePoint list REST interface to get all entries in Acquisition Release Register
Use http://intranet/_vti_bin/listdata.svc to retrieve list entries
Custom claim provider compares current date to entries in Acquisition Release Register
If now is later than release date then add project name to user’s claims
If user has claim in their identity matching acquisition project name, then they will get access to the acquisition documents
Claim Provider Examples
Example 3: Access based on current location (IP Address or Country)
Modify Authenticate.aspx to retrieve user’s IP address
Found: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\template\layoutsCould also retrieve user-agent string – use for browser/device based access
Call out to reverse-IP service to get country, long/lat
Save data to text file in SharePoint server TEMPFile is named with user’s UPN
Custom claim provider looks up user’s UPN in claimsWithin FillClaimsForEntity its found in SPClaim entity parameter
Custom claim provider reads text file and add’s claimsYour mileage may vary – Still Experimental
TopicDeployment and Final Considerations
Deploying Custom Claim Provider
Deployed as a Farm Level Feature Receiver – requires more code
Must inherit from SPClaimProviderFeatureReceiver (lots of examples)
Can deploy multiple claim providersCalled in order of deployment
Once deployed - Available in every web app, in very zoneCan cause performance issuesWhen user logs in, all Custom Claim Providers deployed get called
Set IsUsedByDefault property in Feature Receiver Def'n to False; then turn it on manually for required web apps
Some Final Considerations
Reach out to SQL database, LDAP, Repository for attributes which will get added as claims
Custom Claim Provider running in the context of the web application, and not the site the user is logging into
Logged in as the Central Admin Service Account
Do not have context (Most methods have no HTTP Context nor SPContext.Current)
Cannot directly access data on the Site you signed into
For Debugging use a Claims Testing Web Part in SharePoint:
http://blogs.technet.com/b/speschka/archive/2010/02/13/figuring-out-what-claims-you-have-in-sharepoint-2010.aspx
SponsorsEnterprise
Standard
Join us in Las Vegas for SharePoint Conference 2012!
Don’t miss this opportunity to join us in Las Vegas at the Mandalay Bay November 12-15
Give yourself a competitive edge and get the inside scoop about 'SharePoint 15' while learning how to better use SharePoint 2010
Engage with the community
Share insights
Learn about what’s coming next, from the people who built the product
REGISTER NOW! www.sharepointconference.com