Microsoft Developer Network > 포럼 홈 > Live Framework > Live ID with Active STS / WS-Trust
질문하기질문하기
 

답변됨Live ID with Active STS / WS-Trust

  • 2009년 6월 28일 일요일 오전 4:12Dean Ward 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    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
    • 편집됨Dean Ward 2009년 6월 28일 일요일 오전 4:17
    •  

답변

  • 2009년 6월 28일 일요일 오후 7:30Dean Ward 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    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!
    • 답변으로 표시됨Dean Ward 2009년 6월 28일 일요일 오후 7:30
    •  

모든 응답

  • 2009년 6월 28일 일요일 오후 7:30Dean Ward 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    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!
    • 답변으로 표시됨Dean Ward 2009년 6월 28일 일요일 오후 7:30
    •  
  • 2009년 11월 25일 수요일 오후 3:51greatwhitenorth 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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