Отправить токен ADFS от клиента к службе WCF

У меня есть требование, когда моему приложению 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();

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

Спасибо,


person Bhaskar    schedule 07.09.2011    source источник


Ответы (1)


Вам необходимо: 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) { }
        }
    }

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

person Daniel Miller    schedule 20.02.2012