Home > ShaePoint 2013, SharePoint 2010 > SharePoint Claims to Windows Impersonation context for service calls

SharePoint Claims to Windows Impersonation context for service calls

Scenario:
If you have some custom code running on SharePoint 2010/2013 site (with claim based authentication enabled), you may run into impersonation issues. If your code is calling oData service, web service or WCF service, you will encounter access denied type issues. Everything works local but may fail on test environments. Most of the time, we have our local virtual machine setup or cloud VM setup as windows authentication only and we do not see such issue up front. When custom code is moved into a testing environment, it immediately runs into access denied issues.

Problem:
Code is running in claims context and no user context will be passed to your services. Access denied is expected in this case.

Resolution: 
You can get current user windows identity by calling  Microsoft.IdentityModel.WindowsTokenService.UpnLogon( upnValue ) method and further call identity.impersonate method.

Here is the full line of code
STEP 1 – Add ClaimsToWindowsID class to your project
STEP 2- Call 3 line of code to impersonate the user before your service calls. It will ensure that correct windows ID context is passed to your service calls.

//=STEP 1===ClaimsToWindowsIdHelper===You can keep it in a utils project or as a helper class==

using System;

using System.Security.Principal;

using Microsoft.SharePoint;

using System.ServiceModel.Security;

using System.Threading;

using Microsoft.IdentityModel.WindowsTokenService;

using Microsoft.IdentityModel.Claims;

 

namespace MyProject.SecurityHelper

 

{

 

    /// <summary>

    /// This class helps you to get windows ID context for a claim user.

    /// </summary>

    public static class ClaimsToWindowsIdHelper

    {

        /// <summary>

        /// Retrieves the windows identity for current user based on claim.

        /// </summary>

        /// <returns></returns>

        public static WindowsIdentity GetWindowsIdentityForCurrentClaimUser()

        {

            IClaimsIdentity identity = Thread.CurrentPrincipal.Identity as ClaimsIdentity;

            string upn = null;

 

            if (identity != null)

            {

                foreach (var claim in identity.Claims)

                {

                    if (StringComparer.Ordinal.Equals(System.IdentityModel.Claims.ClaimTypes.Upn, claim.ClaimType))

                    {

                        upn = claim.Value;

                    }

                }

            }

 

            WindowsIdentity windowsIdentity = null;

            if (!String.IsNullOrEmpty(upn))

            {

                try

                {

                    SPSecurity.RunWithElevatedPrivileges(delegate

                    { //claims to windows token call

                        windowsIdentity = S4UClient.UpnLogon(upn);

                    });

                }

                catch (SecurityAccessDeniedException e)

                {

                    // No Upn claim

 

                    throw;

                }

            }

 

            return windowsIdentity;

        }

    }

}

//=======END OF CODE================

 //=STEP 2===call helper and do impersonation======

//You can call this impersonation call any where before your service calls.
WindowsIdentity ctx = null;
ctx = 
MyProject.SecurityHelper.ClaimsToWindowsIdHelper.GetWindowsIdentityForCurrentClaimUser();
if (ctx != null) { ctx.Impersonate();}

 //then your service instantiation, calls can be after the above lines. It means all of the code  after the above lines will be under the windows id context.
//Ofcourse you can add dispose statements, ctx.undo statements in your code after making service calls to go back to claims context if needed and destroy any object.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: