Answered SharePoint Claim with organisational hierarchy

  • Wednesday, April 18, 2012 9:44 AM
     
     

    Hey!

    We are in the process of creating af custom claims provider, and that claims provider is going to contain (among other things) a persons organisational position within our hierarchy.

    Mine is like:

    Defence Department
    - Defence Command
       - IT Agency
           - Infrastructure
                 - Server Applications
                     - SharePoint

    The depth of this hierarchy is very warying - we have between 1 and 17 (!) levels for a person.
    We need to be able to grant access to a site at all levels, and all sub-units must also have access.
    Example: If we grant access to a site to the "Infrastructure" department, all sub-departments/sub-groups must get access

    Now, the question is how to "create" this hierarchy in a sharepoint claim??

    Right now, I have implemented (but not tested yet) it by creating 25 claims named "OrgLevelXX" where X is a number from 1 to 25.
    So every user gets their organisational structure mapped into these claims.

    Meaning that if we use the example above, granting access to "Infrastructure",  we would grant access to the Claim "OrgLevel04" with a value of "Infrastrukture".
    My claims would be:

    http://claims/defence/2012/OrgLevel01 = Defence Deparment
    http://claims/defence/2012/OrgLevel02 = Defence Command
    http://claims/defence/2012/OrgLevel03 = IT Agency
    http://claims/defence/2012/OrgLevel04 = Infrastructure
    http://claims/defence/2012/OrgLevel05 = Server Applications
    http://claims/defence/2012/OrgLevel06 = SharePoint

    So I would be granted access.

    But is this the "correct" way of doing it? It seems rather cumbersome to create all these claims, but I can't figure out if there is a better ways of doing it - ANY comments welcome!

    My initial thought was that I could just create ONE claim containing an array ID's (all organisational units have a unique ID), but all of my Googling and Binging have turned up short...
    Surely someone out there have tried this :-)

    Hope some of you can help with a more "elegant" path resolving this puzzle.

    Thanks for your time!

    Regards
    Jesper Schioett
    Staff Sergeant, Danish Defence IT Agency 

All Replies

  • Wednesday, April 18, 2012 11:44 AM
     
      Has Code
    I guess i'd prefer to create a single claim and put xml it. Keep it very lean, like
    <l>Defence department<l>Defence Command</l></l>
    I don't like the idea of all these claims you're creating, and I think an array isn't expressive enough to reflect the info you're putting in it. In the future, you'll be thankful for the xml as I'm sure there'll come a time when you need to keep track of additional info about the infrastructure.

    Kind regards,
    Margriet Bruggeman

    Lois & Clark IT Services
    web site: http://www.loisandclark.eu
    blog: http://www.sharepointdragons.com


  • Wednesday, April 18, 2012 12:10 PM
     
     

    I know its messy - but doing it the way you propose, I'm not sure would work...

    The thing is - when I said array, I ment some form of what you are suggesting - just creating a claim with the value "1231456#654564#1898151#46846564#54654" (all of the ID's for the different units).

    But, this will only work, if SharePoint matches claims with a "Like" kinda operator.

    Would SharePoint grant access to a site demanding claim value of "654564" if I presented it with "1231456#654564#1898151#46846564#54654" ????
    I would think not, and then your suggestion wouldn't work.

    I'm relying on SharePoints own abillity the check claims - my custom claimsprovider doesn't get asked everytime there is an authorization reguest for a site...

    I'm hoping I'm wrong in my assumption, but from a security perspective matching claim values with a "Like" operator seems "not good" :-)
    (If it does - I could just demand a claim value of "a" and then every user having an "a" somewhere in that claim would get access)

    If it on the other hand, does recognize an "array-like" value of a claim, that it could match up against - perfect... but then, how do I construct such an array?

    Regards
    Jesper Schioett
    Staff Sergeant, Danish Defence IT Agency


    • Edited by Schioett Wednesday, April 18, 2012 12:12 PM
    •  
  • Wednesday, April 18, 2012 1:36 PM
     
      Has Code
    Ah, I see. I was under the impression that you'd do something like in http://sharepointdragons.com/2012/01/30/claims-in-sharepoint-2010/ :
    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Microsoft.IdentityModel.Claims;
     
    namespace LCWebParts.ClaimsVisualPart
    {
        public partial class ClaimsVisualPartUserControl : UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                IClaimsIdentity cidentity = (IClaimsIdentity) Page.User.Identity;
                Label1.Text = String.Format(“User name = {0}<br/>”, cidentity.Name);
                
                foreach (Claim claim in cidentity.Claims)
                {
                    Label1.Text += String.Format(“type: {0} value = {1}<br/>”, claim.ClaimType, claim.Value);
                }            
            }
        }
    }
    

    In which the XML approach (or array) would be fine. Now I see you're doing something like: http://blog.mastykarz.nl/programmatically-granting-permissions-claims/ In that case, I don't see you have a choice but to add the separate claims.

    Kind regards,
    Margriet Bruggeman

    Lois & Clark IT Services
    web site: http://www.loisandclark.eu
    blog: http://www.sharepointdragons.com

  • Wednesday, April 18, 2012 2:13 PM
     
     

    Ohh, well... That's what I thought :-)

    Still hoping thou, that some genius out there have a nicer solution - it is really cumbersome to create all those claims (plus I have created an additionel number of Org claims "for future usage" - sucks)

    Thanks for the effort Margriet!

    Any MS/Other hardcore claims developers out there?
    I'm thinking this actually must be a quite common scenario for claims use, no?

    Regards
    Jesper Schioett
    Staff Sergeant, Danish Defence IT Agency

  • Friday, April 20, 2012 5:24 AM
     
     

    Well, I searched around a bit, and stumbled over this post:

    http://sharepointmetadataandclassification.typepad.com/blog/2012/03/building-a-custom-claim-provider-to-manage-security-clearances.html

    Here this guy is trying to archive some kind of hierarchy in the way a security clearance is applied.
    Hes does it by adding the same claim (example: http://claim/whatever/clearance ) a number of times with different values...

    Can you do this? I allways thought that a claim needed to be unique (as in there can only exist ONE http://claim/whatever/clearance claim)

    If you can do this, then I could just add my "tree" by adding a Organization claim a number of times with my different unit ID's.

    So instead of this (what I do now) having 25 unique claims:

    http://claims/defence/2012/OrgLevel01 = Defence Deparment
    http://claims/defence/2012/OrgLevel02 = Defence Command
    http://claims/defence/2012/OrgLevel03 = IT Agency
    http://claims/defence/2012/OrgLevel04 = Infrastructure
    http://claims/defence/2012/OrgLevel05 = Server Applications
    http://claims/defence/2012/OrgLevel06 = SharePoint
    http://claims/defence/2012/OrgLevel07 = <empty>
    http://claims/defence/2012/OrgLevel08 = <empty>
    ...
    http://claims/defence/2012/OrgLevel25 = <empty>

    I could just have a repeated claim 6 times:

    http://claims/defence/2012/Organization = Defence Deparment
    http://claims/defence/2012/Organization = Defence Command
    http://claims/defence/2012/Organization= IT Agency
    http://claims/defence/2012/Organization= Infrastructure
    http://claims/defence/2012/Organization= Server Applications
    http://claims/defence/2012/Organization= SharePoint

    That would tiddy up my code A LOT, and make a couple of my functions much more streamlined...

    So, what say you?


    Regards Jesper Schioett Staff Sergeant, Danish Defence IT Agency

  • Friday, April 20, 2012 5:35 AM
     
     
    This is certainly turning out to be an interesting problem, i'll probably find some time to play around with it next week. Reading the article, it sure sounds promising. That would be the elegant solution you were looking for. I'm very interested to hear how this turns out.

    Kind regards,
    Margriet Bruggeman

    Lois & Clark IT Services
    web site: http://www.loisandclark.eu
    blog: http://www.sharepointdragons.com

  • Tuesday, April 24, 2012 12:28 PM
     
     Answered Has Code

    Don't know if you figured it out yet, but the article you've mentioned ( http://sharepointmetadataandclassification.typepad.com/blog/2012/03/building-a-custom-claim-provider-to-manage-security-clearances.html ) provides the answer. The most important method is this one:

    		protected override void FillClaimsForEntity(Uri context, SPClaim entity, List<SPClaim> claims)
    		{
    			if (entity == null) throw new ArgumentNullException("empty entity");
    			if (claims == null) throw new ArgumentNullException("empty claims");
    			if (String.IsNullOrEmpty(entity.Value)) throw new ArgumentException("no entityvalue");
    
    			// claim type = http://schemas.loisandclark.eu/myclearance
    			bool top = DoesClaimValueAlreadyExist(claims, ClearanceClaimType, "Top Secret");
    			bool secret = DoesClaimValueAlreadyExist(claims, ClearanceClaimType, "Secret");
    			bool confidential = DoesClaimValueAlreadyExist(claims, ClearanceClaimType, "Confidential");
    			bool none = DoesClaimValueAlreadyExist(claims, ClearanceClaimType, "None");
    
    			// None
    			claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[0], ClearanceClaimValueType));
    			
    			// Confidential
    			claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[1], ClearanceClaimValueType));
    			claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[2], ClearanceClaimValueType));
    			claims.Add(CreateClaim(ClearanceClaimType, SecurityLevels[3], ClearanceClaimValueType));
    	
    		}
    It allows you to assign multiple values to a unique claim type, thereby allowing you to implement the scenario you want. You can verify this by taking a look at the screenshot below, where I've added multiple claims of the same claim type (the closest you can get):

    I've also used these individual claim values to assign permissions on SharePoint objects and it worked perfectly. Can you confirm that this is indeed the answer so we can close this (interesting) thread.


    Kind regards,
    Margriet Bruggeman

    Lois & Clark IT Services
    web site: http://www.loisandclark.eu
    blog: http://www.sharepointdragons.com









  • Thursday, April 26, 2012 2:42 PM
     
     Answered
    Since I found the topic interesting and as a form of closure I've written the following blog post about it: http://sharepointdragons.com/2012/04/26/claims-in-sharepoint-2010-the-sequel/

    Kind regards,
    Margriet Bruggeman

    Lois & Clark IT Services
    web site: http://www.loisandclark.eu
    blog: http://www.sharepointdragons.com

  • Saturday, April 28, 2012 7:49 PM
     
     

    Hey Margriet

    Yep found it out my self - while surfing around, I stumbled over this:

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

    So, like you - I tried it out and it works - much nicer code and I'm not limited to a certain amount of "levels" - super.

    Nice blogpost - I'll try not to shoot you ;-)
    I'm thinking I might do a post my self, just to document how I made the Claims Provider - there really isn't a "complete" enterprise ready feature rich demo of a custom claims provider out there (yours is close!)

    Now on to the next problem :-) - thanks for your time!


    Regards Jesper Schioett Staff Sergeant, Danish Defence IT Agency