Отправка токена ADFS с клиента в службу WCF - PullRequest
0 голосов
/ 07 сентября 2011

У меня есть требование, чтобы в моем приложении Silverlight требовалось подключаться к службе WCF для извлечения данных через промежуточную службу WCF, которая размещена в том же домене, что и Silverlight.То есть Silverlight собирается позвонить в промежуточную службу, которая присоединит IssuedToken вместе с запросом и отправит его основному клиенту WCF.Основная служба WCF будет извлекать заявки из Thread.Principal.

    var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
    binding.Security.Message.EstablishSecurityContext = false;

    var factory = new ChannelFactory<IMyService>(binding, new EndpointAddress("https://myservice.cloudapp.net:4432/MyService.svc"));
    var channel = factory.CreateChannelActingAs(((ClaimsIdentity)((ClaimsPrincipal)HttpContext.Current.User).Identity).BootstrapToken);

    var data = channel.GetData();

Но этот фрагмент кода завершается ошибкой.Я не могу найти документацию о том, как этого добиться.Может кто-нибудь, пожалуйста, помогите мне с этим.

Спасибо,

1 Ответ

1 голос
/ 20 февраля 2012

Вам необходимо: 1. выполнить аутентификацию напротив службы ADFS STS, чтобы получить SecurityToken 2. запросить вашу службу с помощью канала, используя «CreateChannelWithIssuedToken», в соответствии с:

        var token = GetToken();

        string uri = SERVICE_URL;

        EndpointAddress address = new EndpointAddress(uri);

        var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
        binding.Security.Message.EstablishSecurityContext = false;

        _factory = new ChannelFactory<IService>(binding, address);
        _factory.ConfigureChannelFactory<IService>();
        _factory.Credentials.SupportInteractive = false;

        _service = _factory.CreateChannelWithIssuedToken<IService>(token);

кодом для GetTokenбудет выглядеть следующим образом:

    public static SecurityToken GetToken(string username, string password, EndpointAddress federationServiceProxyAddress, EndpointAddress relyingPartyIdentifier)
    {
        var binding = new UserNameWSTrustBinding
        {
            SecurityMode = SecurityMode.TransportWithMessageCredential
        };

        var factory = new WSTrustChannelFactory(binding, federationServiceProxyAddress)
        {
            TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13,
        };

        factory.Credentials.SupportInteractive = false;
        factory.Credentials.UserName.UserName = username;
        factory.Credentials.UserName.Password = password;

        try
        {
            var requestSecurityToken = new RequestSecurityToken
            {
                RequestType = WSTrust13Constants.RequestTypes.Issue,
                AppliesTo = relyingPartyIdentifier
            };

            var channel = factory.CreateChannel();
            return channel.Issue(requestSecurityToken);//, out requestSecurityTokenResponse);
        }
        catch (MessageSecurityException exception)
        {
            // Invalid username or password
            throw new MessageSecurityException(exception.Message, exception);
        }
        catch (Exception exception)
        {
            // Unknown error
            throw new Exception(exception.Message, exception);
        }
        finally
        {
            try
            {
                if (factory.State == CommunicationState.Faulted)
                {
                    factory.Abort();
                }
                else
                {
                    factory.Close();
                }
            }
            catch (Exception) { }
        }
    }

Надеюсь, это поможет ...

...