Microsoft Developer Network > Página principal de foros > Live Framework > Live ID with Active STS / WS-Trust
Formular una preguntaFormular una pregunta
 

RespondidaLive ID with Active STS / WS-Trust

  • domingo, 28 de junio de 2009 4:12Dean Ward Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Tiene código
    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
    • EditadoDean Ward domingo, 28 de junio de 2009 4:17
    •  

Respuestas

  • domingo, 28 de junio de 2009 19:30Dean Ward Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida
    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!
    • Marcado como respuestaDean Ward domingo, 28 de junio de 2009 19:30
    •  

Todas las respuestas

  • domingo, 28 de junio de 2009 19:30Dean Ward Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     Respondida
    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!
    • Marcado como respuestaDean Ward domingo, 28 de junio de 2009 19:30
    •  
  • miércoles, 25 de noviembre de 2009 15:51greatwhitenorth Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     
    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