/// <summary> /// Generates the info hash section for HealthVault service /// web requests given the specified data beginning at the specified /// index. /// </summary> /// /// <param name="buffer"> /// An array of bytes representing the UTF8 encoded data. /// </param> /// /// <param name="index"> /// An integer representing the starting location in the byte array. /// </param> /// /// <param name="count"> /// An integer representing the count of bytes. /// </param> /// /// <returns> /// A string representing the info hash. /// </returns> /// internal static string CreateInfoHash(Byte[] buffer, int index, int count) { CryptoHash hash = new CryptoHash(); hash.ComputeHash(buffer, index, count); return hash.Finalize().GetXml(); }
/// <summary> /// /// </summary> /// /// <param name="appId"></param> /// <param name="ticket"></param> /// <param name="sharedSecret"></param> /// /// <param name="isMra"> /// True if the application is a multi-record application, or false otherwise. Multi-record /// applications can work with many user records at one time and does not rely on the /// selected record when performing operations. /// </param> /// /// <param name="isPersistent"> /// True if creating a persistent token, or false otherwise. Persistent connections /// remain valid for the duration specified in the application's configuration within /// HealthVault. Typically, persistent tokens are valid for up to one year. /// </param> /// /// <param name="cancelTrigger"></param> /// <param name="shellUrl"></param> /// /// <returns></returns> /// /// <exception cref ="HealthServiceException"> /// If the request results in an error being returned from the Shell. The /// <see cref="HealthServiceException.ErrorCode"/> can give more details about the error /// that occurred. /// </exception> /// /// <exception cref="HealthRecordAuthorizationRequiredException"> /// If the user could not be logged in because they have not authorized the application to /// a health record. The application should direct the user to the APPAUTH target of the /// Shell. /// </exception> /// /// <exception cref="HealthRecordAuthorizationNotPossible"> /// If the user does not have access to a health record that meets the minimum authorization /// requirements of the application. The user will need to request more access from the /// custodian to use this application. /// </exception> /// /// <exception cref="HealthRecordReauthorizationRequired"> /// If the user had authorized a health record for this application but the application /// changed its required base authorizations such that the user must reauthorize the /// application. The application should direct the user to the APPAUTH target of the Shell. /// </exception> /// private static string VerifyTicketWithShell( Guid appId, string ticket, CryptoHash sharedSecret, bool isMra, bool isPersistent, ManualResetEvent cancelTrigger, Uri shellUrl) { ShellResponseHandler handler = new ShellResponseHandler(); EasyWebRequest request = new EasyWebRequest(); request.ForceAsyncRequest = true; request.RequestCompressionMethod = String.Empty; if (cancelTrigger != null) { request.RequestCancelTrigger = cancelTrigger; } // Add the Authorization header for passport verification string ticketHeader = Convert.ToBase64String( new UTF8Encoding().GetBytes("WLID1.0 t=" + ticket)); request.Headers.Add( "LiveIdTicket", ticketHeader); // Add the shared secret header for creating the session token string sharedSecretHeader = Convert.ToBase64String( new UTF8Encoding().GetBytes(sharedSecret.GetInfoXml())); request.Headers.Add( "SharedSecret", sharedSecretHeader); string authToken = null; try { Uri liveIdTicketVerifierUrl = new Uri( shellUrl, "redirect.aspx?target=verifyliveid&targetqs=" + HttpUtility.UrlEncode( "?appid=" + appId + "&ismra=" + SDKHelper.XmlFromBool(isMra) + "&persistwctoken=" + SDKHelper.XmlFromBool(isPersistent))); request.Fetch(liveIdTicketVerifierUrl,handler); ApplicationRecordAuthorizationAction action = ApplicationRecordAuthorizationAction.Unknown; XmlReader infoReader = handler.Response.InfoReader; if (SDKHelper.ReadUntil(infoReader, "token")) { if (infoReader.MoveToAttribute("app-record-auth-action")) { try { action = (ApplicationRecordAuthorizationAction)Enum.Parse( typeof(ApplicationRecordAuthorizationAction), infoReader.Value); } catch (ArgumentException) { } } } switch (action) { case ApplicationRecordAuthorizationAction.NoActionRequired : break; case ApplicationRecordAuthorizationAction.AuthorizationRequired : throw new HealthRecordAuthorizationRequiredException(); case ApplicationRecordAuthorizationAction.ReauthorizationNotPossible : throw new HealthRecordAuthorizationNotPossible(); case ApplicationRecordAuthorizationAction.ReauthorizationRequired : throw new HealthRecordReauthorizationRequired(); default : throw new HealthServiceException( HealthServiceStatusCode.RecordAuthorizationFailure); } infoReader.MoveToElement(); authToken = infoReader.ReadElementContentAsString(); } catch (WebException webException) { if (((HttpWebResponse)webException.Response).StatusCode == HttpStatusCode.Forbidden) { throw new HealthServiceAccessDeniedException( webException.Message, webException); } throw; } finally { if (request != null) { request.Dispose(); request = null; } } return authToken; }