Enable Cookie in WCF Windows azure service

Proposed Answer Enable Cookie in WCF Windows azure service

  • Donnerstag, 17. Mai 2012 09:47
     
     

    hi,

    I deployed the wcf service as web role to the windows azure , which is used to get the date from the sharepoint 365. Now the problem is that in the code i am using the cookie to make the subsequent request to the sharepoin 365 in order to authenticate the user. The code is working fine when the azure servie is ran on the local system in the emulator, but it give exception when i try to access the services hosted on the azure [staging enviornment].

    Please help me out in this, does i need to do any configuration setting to enable the cookie on the hosting enviornment on azure.


    regards Vimal

Alle Antworten

  • Donnerstag, 17. Mai 2012 11:30
    Moderator
     
     

    Hi,

    I suggest you post the exception and stack message on this thread, it's helpful for us to solve this problem, i think.

    I am not 100% sure, you are trying to use Cookies in WCF web role, right? HttpCookie or client cookie? Can you make sure your WCF web role in Cloud has receive the Cookie variable success?

    BR,

    Arwind  


    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework

  • Samstag, 19. Mai 2012 05:02
     
     

    hi 

    the error i am getting is , and the link i am referring is  

    http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx

    to connect to Sharepoint 365 with windows azure wcf service. 

    System.NullReferenceException: Object reference not set to an instance of an object.

       at Wictor.Office365.MsOnlineClaimsHelper.getCookieContainer().




    regards Vimal

  • Samstag, 19. Mai 2012 14:47
     
     

    hi

    I have a simple service that you can access here:

    http://xxxxxxxxxxxxxxxxxxxxxxx.cloudapp.net/MyTestService.svc

    But the link to the wsdl uses the internal machine name instead of the public Url, like this:

    svcutil.exe http://rd001520d328923a/MyTestService.svc?wsdl

    Obviously, the wsdl is not accessible.

    i don't know how to correct this please help me  out?


    regards Vimal

  • Montag, 21. Mai 2012 06:12
     
      Enthält Code

    Hi,

    change the sessionstate to SQLServer

    http://msdn.microsoft.com/en-us/library/h6bb9cz9%28v=vs.71%29.aspx

    Since azure is a distributed system, session must be handled such

    <sessionState mode="SQLServer" sqlConnectionString="Server=tcp:server.database.windows.net,1433;Database=user;User ID=user@server;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" cookieless="false" timeout="30" allowCustomSqlDatabase="true" sqlCommandTimeout="300">
    </sessionState>

    Regards

    Madan

    dmadan.wordpress.com




  • Montag, 21. Mai 2012 07:27
     
     

    hi

    thanks for replying,

    can you please tell me where should i add this session state tag, since i am not using any sql db in my aure so i don't have the connection string , and also i have WCF web config file only .


    regards Vimal

  • Dienstag, 22. Mai 2012 15:45
     
      Enthält Code

    Here is the example

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.web>
    <sessionState mode="SQLServer" sqlConnectionString="Server=tcp:server.database.windows.net,1433;Database=user;User ID=user@server;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" cookieless="false" timeout="30" allowCustomSqlDatabase="true" sqlCommandTimeout="300">
    </sessionState>
      </system.web>
    </configuration>
    
    

    Regards

    Madan

    dmadan.wordpress.com

  • Dienstag, 22. Mai 2012 16:19
     
     

    hi

    but i don't have sql azure instance running , so will this same connection string will work . will i put this session state tag to my azure wcf config file.


    regards Vimal

  • Mittwoch, 23. Mai 2012 14:08
     
     Vorgeschlagene Antwort Enthält Code

    You can use Table storage instead of SQL Azure in this case

        <sessionState mode="Custom"
               customProvider="TableStorageSessionStateProvider">
            <providers>
              <clear/>
                <add name="TableStorageSessionStateProvider" type=  "Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
                     applicationName="yourWebAppName"/>
            </providers>
        </sessionState>
    
    Please go through this link http://www.intertech.com/Blog/post/Session-State-in-Windows-Azure.aspx

    Hope this helps

    Madan

    dmadan.wordpress.com

  • Dienstag, 29. Mai 2012 06:27
     
     

    thanks for replying ,

    but this doesn't work, i will be sharing the web config , and the part of code where i am getting exception, this might help.


    regards Vimal

  • Mittwoch, 30. Mai 2012 19:38
     
      Enthält Code

    the error i am getting is 

       

     at Wictor.Office365.MsOnlineClaimsHelper.getCookieContainer() in G:\Practice\SharepointWindowsPhoneService\WCFServiceWebRole1\MsOnlineClaimsHelper.cs:line 89
       at Wictor.Office365.MsOnlineClaimsHelper.clientContext_ExecutingWebRequest(Object sender, WebRequestEventArgs e) in G:\Practice\SharepointWindowsPhoneService\WCFServiceWebRole1\MsOnlineClaimsHelper.cs:line 76
       at Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest()
       at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
       at SharepointAzureService.Win7MobileService.GetxsTranContact(UserDetail userdetial) in G:\Practice\SharepointWindowsPhoneService\WCFServiceWebRole1\Win7MobileService.svc.cs:line 36
       at SyncInvokeGetxsTranContact(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

       ===================

    clientContext_ExecutingWebRequest method giving the error, at get cookiee container method.

    the error getting when trying access the service from cloud

    using System;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.ServiceModel;
    using ClientOmAuth;
    using System.Xml;
    using System.ServiceModel.Channels;
    using Microsoft.IdentityModel.Protocols.WSTrust;
    using System.Web;
    using System.IO;
    using System.Xml.Linq;
    using Microsoft.SharePoint.Client;
    
    namespace Wictor.Office365
    {
        public class MsOnlineClaimsHelper
        {
    
            #region Properties
    
            readonly string _username;
            readonly string _password;
            readonly bool _useRtfa;
            readonly Uri _host;
    
            CookieContainer _cachedCookieContainer = null;
            DateTime _expires = DateTime.MinValue;
    
            #endregion
    
            #region Constructors
            public MsOnlineClaimsHelper(string host, string username, string password)
                : this(new Uri(host), username, password)
            {
    
            }
            public MsOnlineClaimsHelper(Uri host, string username, string password)
            {
                _host = host;
                _username = username;
                _password = password;
                _useRtfa = true;
            }
            public MsOnlineClaimsHelper(Uri host, string username, string password, bool useRtfa)
            {
                _host = host;
                _username = username;
                _password = password;
                _useRtfa = useRtfa;
            }
            #endregion
    
            #region Constants
            public const string office365STS = "https://login.microsoftonline.com/extSTS.srf";
            public const string office365Login = "https://login.microsoftonline.com/login.srf";
            public const string office365Metadata = "https://nexus.microsoftonline-p.com/federationmetadata/2007-06/federationmetadata.xml";
            public const string wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
            public const string wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
            private const string userAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
            #endregion
    
    
    
            class MsoCookies
            {
                public string FedAuth { get; set; }
                public string rtFa { get; set; }
                public DateTime Expires { get; set; }
                public Uri Host { get; set; }
            }
    
            // Method used to add cookies to CSOM
            public void clientContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
            {
                e.WebRequestExecutor.WebRequest.CookieContainer = getCookieContainer();
                //e.WebRequestExecutor.WebRequest.UserAgent = userAgent;
            }
    
            // Creates or loads cached cookie container
            CookieContainer getCookieContainer()
            {
                if (_cachedCookieContainer == null || DateTime.Now > _expires)
                {
    
                    // Get the SAML tokens from SPO STS (via MSO STS) using fed auth passive approach
                    MsoCookies cookies = getSamlToken();
    
                    if (!string.IsNullOrEmpty(cookies.FedAuth))
                    {
    
                        // Create cookie collection with the SAML token                    
                        _expires = cookies.Expires;
                        CookieContainer cc = new CookieContainer();
    
                        // Set the FedAuth cookie
                        Cookie samlAuth = new Cookie("FedAuth", cookies.FedAuth)
                        {
                            Expires = cookies.Expires,
                            Path = "/",
                            Secure = cookies.Host.Scheme == "https",
                            HttpOnly = true,
                            Domain = cookies.Host.Host
                        };
                        cc.Add(samlAuth);
    
    
                        if (_useRtfa)
                        {
                            // Set the rtFA (sign-out) cookie, added march 2011
                            Cookie rtFa = new Cookie("rtFA", cookies.rtFa)
                            {
                                Expires = cookies.Expires,
                                Path = "/",
                                Secure = cookies.Host.Scheme == "https",
                                HttpOnly = true,
                                Domain = cookies.Host.Host
                            };
                            cc.Add(rtFa);
                        }
                        _cachedCookieContainer = cc;
                        return cc;
                    }
                    return null;
                }
                return _cachedCookieContainer;
            }
    
            public CookieContainer CookieContainer
            {
                get
                {
                    if (_cachedCookieContainer == null || DateTime.Now > _expires)
                    {
                        return getCookieContainer();
                    }
                    return _cachedCookieContainer;
                }
            }
    
            private MsoCookies getSamlToken()
            {
                MsoCookies ret = new MsoCookies();
    
                try
                {
                    var sharepointSite = new
                    {
                        Wctx = office365Login,
                        Wreply = _host.GetLeftPart(UriPartial.Authority) + "/_forms/default.aspx?wa=wsignin1.0"
                    };
    
                    //get token from STS
                    string stsResponse = getResponse(office365STS, sharepointSite.Wreply);
    
                    // parse the token response
                    XDocument doc = XDocument.Parse(stsResponse);
    
                    // get the security token
                    var crypt = from result in doc.Descendants()
                                where result.Name == XName.Get("BinarySecurityToken", wsse)
                                select result;
    
                    // get the token expiration
                    var expires = from result in doc.Descendants()
                                  where result.Name == XName.Get("Expires", wsu)
                                  select result;
                    ret.Expires = Convert.ToDateTime(expires.First().Value);
    
    
                    HttpWebRequest request = createRequest(sharepointSite.Wreply);
                    byte[] data = Encoding.UTF8.GetBytes(crypt.FirstOrDefault().Value);
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                        stream.Close();
    
                        using (HttpWebResponse webResponse = request.GetResponse() as HttpWebResponse)
                        {
    
                            // Handle redirect, added may 2011 for P-subscriptions
                            if (webResponse.StatusCode == HttpStatusCode.MovedPermanently)
                            {
                                HttpWebRequest request2 = createRequest(webResponse.Headers["Location"]);
                                using (Stream stream2 = request2.GetRequestStream())
                                {
                                    stream2.Write(data, 0, data.Length);
                                    stream2.Close();
    
                                    using (HttpWebResponse webResponse2 = request2.GetResponse() as HttpWebResponse)
                                    {
                                        ret.FedAuth = webResponse2.Cookies["FedAuth"].Value;
                                        ret.rtFa = webResponse2.Cookies["rtFa"].Value;
                                        ret.Host = request2.RequestUri;
                                    }
                                }
                            }
                            else
                            {
                                ret.FedAuth = webResponse.Cookies["FedAuth"].Value;
                                ret.rtFa = webResponse.Cookies["rtFa"].Value;
                                ret.Host = request.RequestUri;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    return null;
                }
                return ret;
            }
    
            static HttpWebRequest createRequest(string url)
            {
                HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.CookieContainer = new CookieContainer();
                request.AllowAutoRedirect = false; // Do NOT automatically redirect
                request.UserAgent = userAgent;
                return request;
            }
    
            private string getResponse(string stsUrl, string realm)
            {
    
                RequestSecurityToken rst = new RequestSecurityToken
                {
                    RequestType = WSTrustFeb2005Constants.RequestTypes.Issue,
                    AppliesTo = new EndpointAddress(realm),
                    KeyType = WSTrustFeb2005Constants.KeyTypes.Bearer,
                    TokenType = Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml11TokenProfile11
                };
    
                WSTrustFeb2005RequestSerializer trustSerializer = new WSTrustFeb2005RequestSerializer();
    
                WSHttpBinding binding = new WSHttpBinding();
    
                binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
    
                binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
                binding.Security.Message.EstablishSecurityContext = false;
                binding.Security.Message.NegotiateServiceCredential = false;
    
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
    
                EndpointAddress address = new EndpointAddress(stsUrl);
    
                using (WSTrustFeb2005ContractClient trustClient = new WSTrustFeb2005ContractClient(binding, address))
                {
                    trustClient.ClientCredentials.UserName.UserName = _username;
                    trustClient.ClientCredentials.UserName.Password = _password;
                    Message response = trustClient.EndIssue(
                        trustClient.BeginIssue(
                            Message.CreateMessage(
                                MessageVersion.Default,
                                WSTrustFeb2005Constants.Actions.Issue,
                                new RequestBodyWriter(trustSerializer, rst)
                            ),
                            null,
                            null));
                    trustClient.Close();
                    using (XmlDictionaryReader reader = response.GetReaderAtBodyContents())
                    {
                        return reader.ReadOuterXml();
                    }
                }
            }
    
    
        }
    }
    



    regards Vimal

  • Mittwoch, 30. Mai 2012 19:49
     
     

    hi

    https://docs.google.com/open?id=0B3k9OdcYhHCfRGozLXczY1ZKSDg  link for complete source code that i am using , this might help to tell if i am missing something.


    regards Vimal