Social Icons

jueves, 12 de enero de 2012

Sobre Windows Phone 7 y la autenticación con SharePoint

Conectar el teléfono a nuestro entorno de SharePoint era mi proyecto de navidad, y me llevó un rato... Al final conseguí hacerlo así que he pensado en compartir mi alegría. Además, he leído un montón de blogs sobre el tema ¿todos los que hay? y quería aportar mi granito de arena.

Vamos al asunto. Me he creado una clase llamada SPAuthBridge partiend del código de la SDK que puede ser usada para realizar las conexiones con el servidor de SharePoint.
  1. using System;  
  2. using System.IO;  
  3. using System.Net;  
  4. using System.Text;  
  5.   
  6. namespace PhoneUtils.Code  
  7. {  
  8.     public class SPAuthBridge  
  9.     {  
  10.         #region Properties  
  11.         public CookieContainer cookieJar = new CookieContainer();  
  12.   
  13.         string SiteUrl, User;  
  14.         string Password; //This should be securestring, but I don't think it's available in WP7  
  15.         #endregion  
  16.  
  17.         #region Constructors  
  18.         public SPAuthBridge(string SiteUrl, string User, string Password)  
  19.         {  
  20.             this.SiteUrl = SiteUrl;  
  21.             this.User = User;  
  22.             this.Password = Password;  
  23.         }  
  24.         #endregion  
  25.  
  26.         #region Public Methods  
  27.         public void Authenticate()  
  28.         {  
  29.             try  
  30.             {  
  31.                 if (string.IsNullOrEmpty(SiteUrl)) throw new ArgumentOutOfRangeException("The SPAuthBridge was not properly initialized");  
  32.   
  33.                 System.Uri authServiceUri = new Uri(string.Format("{0}/_vti_bin/authentication.asmx", SiteUrl));  
  34.   
  35.                 HttpWebRequest spAuthReq = HttpWebRequest.Create(authServiceUri) as HttpWebRequest;  
  36.                 spAuthReq.CookieContainer = cookieJar;  
  37.                 spAuthReq.Headers["SOAPAction"] = "http://schemas.microsoft.com/sharepoint/soap/Login";  
  38.                 spAuthReq.ContentType = "text/xml; charset=utf-8";  
  39.                 spAuthReq.Method = "POST";  
  40.   
  41.                 //add the soap message to the request  
  42.                 spAuthReq.BeginGetRequestStream(new AsyncCallback(spAuthReqCallBack), spAuthReq);  
  43.             }  
  44.             catch  
  45.             {  
  46.                 TriggerOnAuthenticated(false);  
  47.             }  
  48.         }  
  49.         #endregion  
  50.  
  51.         #region Private Methods  
  52.         private void spAuthReqCallBack(IAsyncResult asyncResult)  
  53.         {  
  54.             string envelope =  
  55.                     @"<?xml version=""1.0"" encoding=""utf-8""?>  
  56.                     <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">  
  57.                       <soap:Body>  
  58.                         <Login xmlns=""http://schemas.microsoft.com/sharepoint/soap/"">  
  59.                           <username>{0}</username>  
  60.                           <password>{1}</password>  
  61.                         </Login>  
  62.                       </soap:Body>  
  63.                     </soap:Envelope>";  
  64.   
  65.             UTF8Encoding encoding = new UTF8Encoding();  
  66.             HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;  
  67.             Stream _body = request.EndGetRequestStream(asyncResult);  
  68.             envelope = string.Format(envelope, User, Password);  
  69.             byte[] formBytes = encoding.GetBytes(envelope);  
  70.   
  71.             _body.Write(formBytes, 0, formBytes.Length);  
  72.             _body.Close();  
  73.   
  74.             request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);  
  75.         }  
  76.   
  77.         private void ResponseCallback(IAsyncResult asyncResult)  
  78.         {  
  79.             try  
  80.             {  
  81.                 HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;  
  82.                 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);  
  83.                 Stream content = response.GetResponseStream();  
  84.   
  85.                 if (request != null && response != null)  
  86.                 {  
  87.                     if (response.StatusCode == HttpStatusCode.OK)  
  88.                     {  
  89.                         using (StreamReader reader = new StreamReader(content))  
  90.                         {  
  91.                             //Put debugging code here  
  92.                             string _responseString = reader.ReadToEnd();  
  93.                             reader.Close();  
  94.                         }  
  95.                     }  
  96.                 }  
  97.   
  98.                 //authentication complete  
  99.                 TriggerOnAuthenticated(true);  
  100.             }  
  101.             catch  
  102.             {  
  103.                 TriggerOnAuthenticated(false);  
  104.             }  
  105.         }  
  106.         #endregion  
  107.  
  108.         #region Events  
  109.         public delegate void OnAuthenticatedHandler(bool Success);  
  110.   
  111.         public event OnAuthenticatedHandler OnAuthenticated;  
  112.   
  113.         protected virtual void TriggerOnAuthenticated(bool Success)  
  114.         {  
  115.             if (OnAuthenticated != null)  
  116.                 OnAuthenticated(Success);  
  117.         }  
  118.         #endregion  
  119.     }  
  120. }  

La manera de usar esto es bastante simple, creas el objeto SPAuthBridge y, llamas al método Authenticate y listo, algo así:

  1. StratexWP7SoapClient StratexWP7 = new StratexWP7SoapClient(); //This is my web service  
  2. SPAuthBridge SharePointAuth;  
  3.   
  4. public MainPage()  
  5. {  
  6.     InitializeComponent();  
  7.   
  8.     (...)  
  9.   
  10.     SharePointAuth = new SPAuthBridge(SiteUrl, Username, Password);  
  11.     SharePointAuth.OnAuthenticated += new SPAuthBridge.OnAuthenticatedHandler(SharePointAuth_OnAuthenticated);  
  12.   
  13.     if (!string.IsNullOrEmpty(Password))  
  14.         SharePointAuth.Authenticate();  
  15.     else  
  16.         MessageBox.Show("The application should be configured before use.");  
  17. }  
  18.   
  19. void SharePointAuth_OnAuthenticated(bool Success)  
  20. {  
  21.     if (!Success)  
  22.     {  
  23.         Deployment.Current.Dispatcher.BeginInvoke(() =>  
  24.             { MessageBox.Show("There was an error on the authentication procedure. Please check the configuration."); });  
  25.   
  26.         return;  
  27.     }  
  28.   
  29.     StratexWP7.CookieContainer = SharePointAuth.cookieJar; //This is all you have to do to connect your web service. \m/ O.O \m/  
  30.   
  31.     HookEvents();  
  32.   
  33.     RequestData();  
  34. }  

Es precioso cuando funciona…

clip_image002clip_image002[4]
(Por cierto, las gráficas son de AmCharts)

No hay comentarios: