MSDN > Home page del forum > Live Framework > Live ID with Active STS / WS-Trust
Formula una domandaFormula una domanda
 

Con rispostaLive ID with Active STS / WS-Trust

  • domenica 28 giugno 2009 4.12Dean Ward Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Contiene codice
    Hi all,

    I'm attempting to use Geneva's WSTrustClient to retrieve a token from Live ID that is subsequently passed to a WCF service hosted in Azure, using .NET Access Control Services as its STS.

    Whenever I execute an Issue request from WSTrustClient to the endpoint at https://dev.login.live.com/wstlogin.srf, I get an Internal Server Error 500 with no other information

    Looking at the outgoing traffic using fiddler shows the following SOAP envelope (names changed to protect the innocent!):

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <s:Header>
        <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
        <ClientInfo xmlns="http://schemas.microsoft.com/wlid">
          <ApplicationID>1234567890</ApplicationID>
        </ClientInfo>
        <a:MessageID>urn:uuid:dbc9fbc5-e051-41e4-8700-037cb6809de9</a:MessageID>
        <a:ReplyTo>
          <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">https://dev.login.live.com/wstlogin.srf</a:To>
        <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <u:Timestamp u:Id="_0">
            <u:Created>2009-06-28T03:53:28.052Z</u:Created>
            <u:Expires>2009-06-28T03:58:28.052Z</u:Expires>
          </u:Timestamp>
          <o:UsernameToken u:Id="uuid-617af7d6-fd7e-496c-8828-e32323c58018-1">
            <o:Username>username@domain.com</o:Username>
            <o:Password o:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
          </o:UsernameToken>
        </o:Security>
      </s:Header>
      <s:Body>
        <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
          <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
            <a:EndpointReference>
              <a:Address>http://solutionname.accesscontrol.windows.net/issued_for_certificate</a:Address>
            </a:EndpointReference>
          </wsp:AppliesTo>
          <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
        </t:RequestSecurityToken>
      </s:Body>
    </s:Envelope>
    

    The ApplicationID was retrieved from the project settings in the Azure development portal. Am I doing something wrong here? It looks as though it should work?! The code I'm using is:
    class Program
    {
        static void Main(string[] args)
        {
            SecurityToken securityToken;
            using (WSTrustClient wsTrustClient = CreateWSTrustClient())
            {
                wsTrustClient.ClientCredentials.UserName.UserName = "username@domain.com";
                wsTrustClient.ClientCredentials.UserName.Password = "password";
                RequestSecurityToken requestToken = new RequestSecurityToken(RequestTypeConstants.Issue);
                requestToken.AppliesTo = new EndpointAddress("http://solutionname.accesscontrol.windows.net/issued_for_certificate");
                using (new OperationContextScope(wsTrustClient.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageHeaders.Add(
                        new LiveClientInfoHeader
                        {
                            ApplicationId = "1234567890"
                        });
    
                    RequestSecurityTokenResponse requestTokenResponse;
                    securityToken = wsTrustClient.Issue(requestToken, out requestTokenResponse);
                }
            }
        }
    
        private static WSTrustClient CreateWSTrustClient()
        {
            WSHttpBinding wsHttpBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
            wsHttpBinding.Security.Message.EstablishSecurityContext = false;
            wsHttpBinding.Security.Message.NegotiateServiceCredential = false;
            wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
            wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    
            return new WSTrustClient(
                wsHttpBinding,
                new EndpointAddress("https://dev.login.live.com/wstlogin.srf"),
                TrustVersion.WSTrustFeb2005,
                new ClientCredentials());
        }
    }
    
    private class LiveClientInfoHeader : MessageHeader
    {
        public override string Name
        {
            get { return "ClientInfo"; }
        }
    
        public override string Namespace
        {
            get { return "http://schemas.microsoft.com/wlid"; }
        }
    
        public string ApplicationId
        {
            get;
            set;
        }
    
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteStartElement("ApplicationID", this.Namespace);
            writer.WriteValue(this.ApplicationId);
            writer.WriteEndElement();
        }
    }
    
    Any help would be greatly appreciated!

    Thanks & Regards,

    Dean Ward
    Developer
    iPrinciples Ltd
    • ModificatoDean Ward domenica 28 giugno 2009 4.17
    •  

Risposte

  • domenica 28 giugno 2009 19.30Dean Ward Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    Turns out that the SOAP envelope is in fact valid - if I send directly using WebRequest / WebResponse it works just fine. Appears that WSTrustClient is forcing the HttpWebRequest.SendChunked property to true causing the HTTP request to be sent using chunked encoding! This doesn't work so well with the Live ID STS.

    One for the Geneva team methinks!

    Cheers,

    Dean

    UPDATE: After a brief play with Reflector it seems that chunking is not easy to switch off - it's quite deep down in the plumbing and required for any HTTPS bindings! Hacky workaround for the moment is to use a custom Binding / ChannelFactory / IRequestChannel implementation that eats any GetProperty<T> requests for IChannelBindingProvider. I have no idea what knock-on effects it might have, but I can now successfully obtain tokens from the Live ID WS-Trust endpoint!
    • Contrassegnato come rispostaDean Ward domenica 28 giugno 2009 19.30
    •  

Tutte le risposte

  • domenica 28 giugno 2009 19.30Dean Ward Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    Turns out that the SOAP envelope is in fact valid - if I send directly using WebRequest / WebResponse it works just fine. Appears that WSTrustClient is forcing the HttpWebRequest.SendChunked property to true causing the HTTP request to be sent using chunked encoding! This doesn't work so well with the Live ID STS.

    One for the Geneva team methinks!

    Cheers,

    Dean

    UPDATE: After a brief play with Reflector it seems that chunking is not easy to switch off - it's quite deep down in the plumbing and required for any HTTPS bindings! Hacky workaround for the moment is to use a custom Binding / ChannelFactory / IRequestChannel implementation that eats any GetProperty<T> requests for IChannelBindingProvider. I have no idea what knock-on effects it might have, but I can now successfully obtain tokens from the Live ID WS-Trust endpoint!
    • Contrassegnato come rispostaDean Ward domenica 28 giugno 2009 19.30
    •  
  • mercoledì 25 novembre 2009 15.51greatwhitenorth Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Hey Dean,

    Ok, I stuck my toe in and little did I realize just where this was going!  All I wanted to do is use the Live ID STS to authenticate a user from my SilverLight application.  On a vertical learning curve right now, purely in the design stage right now,  but have things changed in this scenario after the PDC 09?  Any thoughts on authorization technique after authentication?

    Regards,
    Richard