четверг, 10 октября 2013 г.

Вызов веб-сервиса MDS из SharePoint 2013. Имперсонализация.

Веб-сервис обычно MDS настраивается при включенной имперсонализации, и метод аутентификации - windows. Однако из SharePoint вызов кода веб-сервиса происходит от имени IUSR. Чтобы заставить веб-сервис выполняться от имени той учетной записи, под которой пользователь зашел на SharePoint необходимо сделать следующие 2 вещи:

1. Включить службу  Claims To Windows Token Service
2. В коде сделать логон под требуемой учеткой.

Служба стартуется из Центра администрирования SharePoint 2013

System Settings -> Manage Services on server -> Claims To Windows Token Service -> Start

 



Далее необходимо добавить в проект утилиту (взято отсюда)

 
   public class Utility
    {
        public static WindowsIdentity GetWindowsIdentityFromClaimsToken()
        {
            WindowsIdentity wi = null;

            // Run this portion of code as application pool account, so that C2WTS service is called as this account
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                // Get the UPN value of the user from the UPN claim type
                Microsoft.IdentityModel.Claims.IClaimsIdentity identity = ((Microsoft.IdentityModel.Claims.ClaimsIdentity)Thread.CurrentPrincipal.Identity as Microsoft.IdentityModel.Claims.IClaimsIdentity);
                string upn = null;
                foreach (Microsoft.IdentityModel.Claims.Claim claim in identity.Claims.Where(claim => StringComparer.Ordinal.Equals(ClaimTypes.Upn, claim.ClaimType)))
                {
                    upn = claim.Value;
                }

                if (upn == null)
                {
                    throw new Exception(string.Format("Cannot Impersonate {0} since he doesn't have a UPN in his claims", Thread.CurrentPrincipal.Identity.Name));
                }

                // Get a WindowsIdentity from the UPN of the user by calling C2WTS service
                try
                {
                    wi = Microsoft.IdentityModel.WindowsTokenService.S4UClient.UpnLogon(upn);
                }
                catch (System.Exception ex)
                {
                    throw new Exception(string.Format("Impersonation failed. Message: {0}", ex.Message));
                }
            });

            return wi;
        }
    }


Далее можно вызывать методы веб-сервиса:

   
            using (WindowsImpersonationContext ctxt = Utility2.GetWindowsIdentityFromClaimsToken().Impersonate())
            {
                ServiceReference.ServiceClient = client = new ServiceReference.ServiceClient();
                var resultOptions = new MetadataResultOptions();
                resultOptions.Models = ResultType.Identifiers;
                var criteria = new MetadataSearchCriteria();
                criteria.SearchOption = SearchOption.UserDefinedObjectsOnly;

                OperationResult result;
                var models = _client.MetadataGet(new International(), resultOptions, criteria, out result); 
            }