RequestSecurityToken с использованием учетных данных Windows и .net 4.5 WIF

Может ли кто-нибудь указать пример кода для активной выдачи RequestSecurityToken с использованием учетных данных NT?Thread.CurrentPrincipal as ClaimsPrincipal

Сценарий представляет собой веб-приложение asp.net с включенной аутентификацией Windows (поэтому существует аутентифицированная WindowsIdentity). Мое желание состоит в том, чтобы активнее вызывать STS, а не включать passiveRedirect, и делать это с помощью библиотек идентификации .Net 4.5.

Большинство примеров кода, таких какПомощник по претензиям для Windows Phone или жеИспользование Active STS установите учетные данные с помощью ввода имени пользователя / pwd и UserNameWSTrustBinding.

Я думал, что решение может включать в себя олицетворение или призыв кchannelFactory.CreateChannelWithActAsToken() с токеном, созданным из идентификатора Windows.

- Следующий код .Net4.5 действительно получает GenericXmlSecurityToken при обращении к оконечной точке / adfs / services / trust / 13 / windowsmixed. Однако претензии относятся к учетной записи домена, под которой работает сайт, а не к учетной записи домена аутентифицированного пользователя. Когда я переключаю конечную точку на / adfs / services / trust / 13 / kerberossmixed, я получаю "не могу договориться ошибки, описанные в нескольких вопросах и на форумах, но я не могу применить какие-либо предложенные решения с .Net 4.5. Одним из классов, не перенесенных из Microsoft.IdentityModel, является KerberosWSTrustBinding ...

public static void CallSts()
{
    try
    {
        var wsMod = FederatedAuthentication.WSFederationAuthenticationModule;
        var appliesToEp = new EndpointReference(wsMod.Realm);
        var stsEp = new EndpointAddress(new Uri(wsMod.Issuer), EndpointIdentity.CreateSpnIdentity("stsSpn"));

        var msgBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
        msgBinding.Security.Message.EstablishSecurityContext = false;
        msgBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

        using(var factory = new WSTrustChannelFactory(msgBinding, stsEp))
        {
            factory.Credentials.SupportInteractive = false;
            factory.TrustVersion = TrustVersion.WSTrust13;

            var myRst = new RequestSecurityToken
            {
                RequestType = RequestTypes.Issue,
                AppliesTo = appliesToEp,
                KeyType = KeyTypes.Bearer,
            };
                var channel = factory.CreateChannel();
                var stsToken = channel.Issue(myRst) as GenericXmlSecurityToken;

                if(stsToken != null)
                {
                    Log.DebugFormat("Reply Token is {0}", stsToken.GetType().Name);

                    var handlers = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers;
                    var token = handlers.ReadToken(new XmlTextReader(new StringReader(stsToken.TokenXml.OuterXml)));
                    var identity = handlers.ValidateToken(token).First();
                    //TODO write to session
                }
                else
                {
                    Log.Debug("Reply Token is null.");
                }
        }
    }
    catch(Exception ex)
    {
        Log.Error("Rst.Call has failed", ex);
    }
}

Для предложения @leastprivilege я добавлю этот код:

    var user = Thread.CurrentPrincipal as ClaimsPrincipal;
var winId = user.Identity as WindowsIdentity;
if(winId != null)
{
    // shows my domain account after I was prompted for credentials;
    // my domain account does not exist on the client machine, so it is a true domain credential
    Log.DebugFormat("WindowsIdentity Name is {0}", winId.Name);
}
using(winId.Impersonate())
{
    // again, shows my domain account
    Log.DebugFormat("Impersonation Context {0}", WindowsIdentity.GetCurrent(true).Name);
    var channel = factory.CreateChannel();
    var stsToken = channel.Issue(myRst) as GenericXmlSecurityToken;
    // request is issued, but results in SecurityNegotiationException: The caller was not authenticated by the service.
}

Который не с "Звонящий не был аутентифицирован службой, Тот же STS будет аутентифицировать мою учетную запись домена в сценарии пассивного перенаправления ... поэтому, хотя я знаю, что я делаю что-то не так, сама учетная запись должна быть распознана.

Обновить:

Я получил уведомление о том, что этот вопрос получил заметное количество просмотров, поэтому я предложу следующее в качестве одного из обходных путей: хотя мы настроили наши серверы для делегирования (как предложил Доминик ниже), мы все еще не преодолели проблему двойного прыжка. Если я помню, мы сталкиваемся с препятствиями, связанными с простыми политиками управления сетями над нашими локальными ИТ-отделами, которые могут затронуть и любое предприятие. Таким образом, хотя олицетворение с использованием двойного прыжка на сервере с проверкой подлинности Windows не допускается, учетные данные могут быть олицетворены с помощью двойного прыжка с помощью обычной проверки подлинности. Это может или не может быть приемлемой ситуацией (интранет для нашего случая). Если вы это сделаете, вы бы добавили

msgBinding.Security.Message.NegotiateServiceCredential = true;

к вышеупомянутой конфигурации ChannelBinding.

Ответы на вопрос(1)

Ваш ответ на вопрос