开发者

Send ADFS Token From Client to a WCF Service

I have a requirement where-in my Silverlight application needs to connect to a WCF service to fetch data, through an intermediate WCF service, which is hosted in the same domain as the Silverlight. That is, the Silverlight is going to make a call to the Intermediate Service, which will attached the IssuedToken along with the request and send it to the main WCF client. The main WCF service would retrieve the claims from the Thread.Prin开发者_StackOverflow社区cipal.

    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();

But this code piece fails. I am unable to find property documentation on how to achieve this. Can anyone please help me with this.

Thanks,


You need to: 1. authenticate opposite the ADFS STS service to obtain a SecurityToken 2. query your service with a channel using "CreateChannelWithIssuedToken", along the lines of:

        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);

The code for GetToken will look as follows:

    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) { }
        }
    }

Hope this helps...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜