/// <summary> /// Make a GET request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="responseHeaders">Response headers returned.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response (with headers).</returns> public static string GetRequestAndHeaders(string url, AuthorisationToken authorisationToken, out WebHeaderCollection responseHeaders, int?navigationPage = null, int?navigationPageSize = null, string contentTypeOverride = null, string acceptOverride = null) { return(RequestAndHeadersWithoutPayload(RequestMethod.GET, url, authorisationToken, out responseHeaders, navigationPage, navigationPageSize, contentTypeOverride, acceptOverride)); }
/// <summary> /// Make a HEAD request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response.</returns> public static string GetRequest(string url, AuthorisationToken authorisationToken, ServiceType serviceType = ServiceType.OBJECT, int?navigationPage = null, int?navigationPageSize = null, string contentTypeOverride = null, string acceptOverride = null) { return(RequestWithoutPayload(RequestMethod.GET, url, authorisationToken, serviceType, navigationPage, navigationPageSize, contentTypeOverride, acceptOverride)); }
/// <summary> /// Make a POST request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="methodOverride">The method that can be used to override the POST, e.g. to issue a GET with a payload.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response.</returns> public static string PostRequest(string url, AuthorisationToken authorisationToken, string body, ServiceType serviceType = ServiceType.OBJECT, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null) { return(RequestWithPayload(RequestMethod.POST, url, authorisationToken, body, serviceType, methodOverride, contentTypeOverride, acceptOverride)); }
/// <summary> /// Make a POST request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="methodOverride">The method that can be used to override the POST, e.g. to issue a GET with a payload.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="mustUseAdvisory">Flag to indicate whether the object's identifier should be retained.</param> /// <param name="headerFields">Other header fields that need to be included.</param> /// <returns>Response.</returns> public static string PostRequest(string url, AuthorisationToken authorisationToken, string body, ServiceType serviceType = ServiceType.OBJECT, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null, bool?mustUseAdvisory = null, NameValueCollection headerFields = null) { return(RequestWithPayload(RequestMethod.POST, url, authorisationToken, body, serviceType, methodOverride, contentTypeOverride, acceptOverride, mustUseAdvisory, headerFields)); }
/// <summary> /// Make a HEAD request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <returns>Web response headers.</returns> public static WebHeaderCollection HeadRequest(string url, AuthorisationToken authorisationToken) { HttpWebRequest request = CreateHttpWebRequest(RequestMethod.HEAD, url, authorisationToken); WebHeaderCollection responseHeaders = new WebHeaderCollection(); using (WebResponse response = request.GetResponse()) { responseHeaders = response.Headers; } return(responseHeaders); }
public void HMACSHA256AuthorisationTest() { IAuthorisationTokenService service = new HmacShaAuthorisationTokenService(); AuthorisationToken authorisationToken = service.Generate("new", "guest"); Console.WriteLine("Authorisation token is " + authorisationToken.Token + "."); Console.WriteLine("Generated UTC ISO 8601 date is " + authorisationToken.Timestamp + "."); GetSharedSecret sharedSecret = SharedSecret; string sessionToken; bool authorised = service.Verify(authorisationToken, sharedSecret, out sessionToken); Assert.AreEqual(sessionToken, "new"); Assert.IsTrue(authorised); }
/// <summary> /// Verify the authentication header. /// </summary> /// <param name="headers">HTTP request headers.</param> /// <param name="initial">Flag to indicate whether this is the initial verification call.</param> /// <param name="sessionToken">Session token associated with the authentication header.</param> /// <returns>True if the initial authentication header is valid; false otherwise.</returns> protected bool VerifyAuthenticationHeader(HttpRequestHeaders headers, bool initial, out string sessionToken) { bool verified = false; string sessionTokenChecked = null; if (headers != null && headers.Authorization != null) { GetSharedSecret sharedSecret; if (initial) { sharedSecret = InitialSharedSecret; } else { sharedSecret = SharedSecret; } try { if (AuthenticationMethod.Basic.ToString().Equals(headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase)) { AuthorisationToken authorisationToken = new AuthorisationToken { Token = headers.Authorization.ToString() }; IAuthorisationTokenService authorisationTokenService = new BasicAuthorisationTokenService(); verified = authorisationTokenService.Verify(authorisationToken, sharedSecret, out sessionTokenChecked); } else if (AuthenticationMethod.SIF_HMACSHA256.ToString().Equals(headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase)) { string timestamp = HttpUtils.GetTimestamp(headers); AuthorisationToken authorisationToken = new AuthorisationToken { Token = headers.Authorization.ToString(), Timestamp = timestamp }; IAuthorisationTokenService authorisationTokenService = new HmacShaAuthorisationTokenService(); verified = authorisationTokenService.Verify(authorisationToken, sharedSecret, out sessionTokenChecked); } } catch (InvalidSessionException) { verified = false; } } sessionToken = sessionTokenChecked; return(verified); }
/// <summary> /// Make a DELETE request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="serviceType">Service type.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response.</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static string DeleteRequest(string url, AuthorisationToken authorisationToken, ServiceType serviceType = ServiceType.OBJECT, string contentTypeOverride = null, string acceptOverride = null) { WebHeaderCollection responseHeaders; return(MakeRequest(RequestMethod.DELETE, url, authorisationToken, out responseHeaders, serviceType: serviceType, contentTypeOverride: contentTypeOverride, acceptOverride: acceptOverride)); }
/// <summary> /// For Basic authentication, the Timestamp property of the AuthorisationToken will always return null. /// <see cref="IAuthorisationTokenService.Generate(string, string)"/> /// </summary> public AuthorisationToken Generate(string sessionToken, string sharedSecret) { if (string.IsNullOrWhiteSpace(sessionToken)) { throw new ArgumentNullException("sessionToken"); } if (string.IsNullOrWhiteSpace(sharedSecret)) { throw new ArgumentNullException("sharedSecret"); } AuthorisationToken authorisationToken = new AuthorisationToken { Token = AuthenticationMethod.Basic.ToString() + " " + Convert.ToBase64String(Encoding.UTF8.GetBytes(sessionToken + ":" + sharedSecret)), Timestamp = null }; return(authorisationToken); }
/// <summary> /// Make a PUT request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="methodOverride">The method that can be used to override the PUT, e.g. to issue a DELETE with a payload.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response.</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static string PutRequest(string url, AuthorisationToken authorisationToken, string body, ServiceType serviceType = ServiceType.OBJECT, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null) { WebHeaderCollection responseHeaders; return(MakeRequest(RequestMethod.PUT, url, authorisationToken, out responseHeaders, body: body, serviceType: serviceType, methodOverride: methodOverride, contentTypeOverride: contentTypeOverride, acceptOverride: acceptOverride)); }
/// <summary> /// Make a HEAD request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>Response.</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static string GetRequest(string url, AuthorisationToken authorisationToken, ServiceType serviceType = ServiceType.OBJECT, int?navigationPage = null, int?navigationPageSize = null, string contentTypeOverride = null, string acceptOverride = null) { WebHeaderCollection responseHeaders; return(MakeRequest(RequestMethod.GET, url, authorisationToken, out responseHeaders, serviceType: serviceType, navigationPage: navigationPage, navigationPageSize: navigationPageSize, contentTypeOverride: contentTypeOverride, acceptOverride: acceptOverride)); }
/// <summary> /// For Basic authentication, the Timestamp property of the AuthorisationToken is ignored. /// <see cref="IAuthorisationTokenService.Verify(AuthorisationToken, GetSharedSecret, out string)"/> /// </summary> public bool Verify(AuthorisationToken authorisationToken, GetSharedSecret getSharedSecret, out string sessionToken) { if (authorisationToken == null) { throw new InvalidAuthorisationTokenException("Authorisation token is null."); } if (string.IsNullOrWhiteSpace(authorisationToken.Token)) { throw new InvalidAuthorisationTokenException("The authorisation token value is null or empty."); } if (getSharedSecret == null) { throw new ArgumentNullException("getSharedSecret"); } string[] tokens = authorisationToken.Token.Split(' '); if (tokens.Length != 2 || !AuthenticationMethod.Basic.ToString().Equals(tokens[0]) || string.IsNullOrWhiteSpace(tokens[1])) { throw new InvalidAuthorisationTokenException("Authorisation token is not recognised."); } string base64EncodedString = tokens[1]; string combinedMessage = Encoding.ASCII.GetString(Convert.FromBase64String(base64EncodedString)); string[] nextTokens = combinedMessage.Split(':'); if (nextTokens.Length != 2 || string.IsNullOrWhiteSpace(nextTokens[0]) || string.IsNullOrWhiteSpace(nextTokens[1])) { throw new InvalidAuthorisationTokenException("Authorisation token is invalid."); } string sharedSecret = nextTokens[1]; sessionToken = nextTokens[0]; return(sharedSecret.Equals(getSharedSecret(sessionToken))); }
/// <summary> /// Make a HEAD request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="compressPayload">Compress payload flag.</param> /// <param name="serviceType">Service type.</param> /// <returns>Web response headers.</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static WebHeaderCollection HeadRequest( string url, AuthorisationToken authorisationToken, bool compressPayload, ServiceType serviceType = ServiceType.OBJECT) { HttpWebRequest request = CreateHttpWebRequest(RequestMethod.HEAD, url, authorisationToken, compressPayload, serviceType); WebHeaderCollection responseHeaders = new WebHeaderCollection(); try { using (WebResponse response = request.GetResponse()) { responseHeaders = response.Headers; } } catch (Exception e) { if ((e is WebException) && ((WebException)e).Response is HttpWebResponse) { HttpWebResponse httpWebResponse = ((WebException)e).Response as HttpWebResponse; if (httpWebResponse.StatusCode.Equals(HttpStatusCode.Unauthorized)) { throw new AuthenticationException("Request is not authorised (authentication failed).", e); } else if (httpWebResponse.StatusCode.Equals(HttpStatusCode.Forbidden)) { throw new UnauthorizedAccessException("Request is forbidden (access denied).", e); } } throw e; } return(responseHeaders); }
/// <summary> /// <see cref="IAuthorisationTokenService.Generate(string, string)"/> /// </summary> public AuthorisationToken Generate(string sessionToken, string sharedSecret) { if (string.IsNullOrWhiteSpace(sessionToken)) { throw new ArgumentNullException("sessionToken"); } if (string.IsNullOrWhiteSpace(sharedSecret)) { throw new ArgumentNullException("sharedSecret"); } AuthorisationToken authorisationToken = new AuthorisationToken(); // Generate UTC ISO 8601 date string. authorisationToken.Timestamp = DateTime.UtcNow.ToString("o"); // 1. Combine the Token and current date time in UTC using ISO 8601 format. byte[] messageBytes = Encoding.ASCII.GetBytes(sessionToken + ":" + authorisationToken.Timestamp); // 2. Calculate the HMAC SHA 256 using the Consumer Secret and then Base64 encode. byte[] keyBytes = Encoding.ASCII.GetBytes(sharedSecret); string hmacsha256EncodedString; using (HMACSHA256 hmacsha256 = new HMACSHA256(keyBytes)) { byte[] hashMessage = hmacsha256.ComputeHash(messageBytes); hmacsha256EncodedString = Convert.ToBase64String(hashMessage); } // 3. Combine the Token with the resulting string from above separated by a colon. string combinedMessage = sessionToken + ":" + hmacsha256EncodedString; // 4. Base64 encode this string. string base64EncodedString = Convert.ToBase64String(Encoding.ASCII.GetBytes(combinedMessage)); // 5. Prefix this string with the Authentication Method and a space. authorisationToken.Token = AuthenticationMethod.SIF_HMACSHA256.ToString() + " " + base64EncodedString; return(authorisationToken); }
/// <summary> /// Make a GET request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="compressPayload">Compress payload flag.</param> /// <param name="responseHeaders">Response headers returned.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="deleteMessageId">Unique identifier of the SIF Event message to delete.</param> /// <returns>Response (with headers).</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static string GetRequestAndHeaders(string url, AuthorisationToken authorisationToken, bool compressPayload, out WebHeaderCollection responseHeaders, ServiceType serviceType = ServiceType.OBJECT, int?navigationPage = null, int?navigationPageSize = null, string contentTypeOverride = null, string acceptOverride = null, string deleteMessageId = null) { return(MakeRequest(RequestMethod.GET, url, authorisationToken, compressPayload, out responseHeaders, serviceType: serviceType, navigationPage: navigationPage, navigationPageSize: navigationPageSize, contentTypeOverride: contentTypeOverride, acceptOverride: acceptOverride, deleteMessageId: deleteMessageId)); }
/// <summary> /// Make a HTTP request with a payload. /// </summary> /// <param name="requestMethod">Request method, e.g. GET.</param> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="methodOverride">Overrides the method of the request, e.g. to implement a GET with a payload over a POST request.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="mustUseAdvisory">Flag to indicate whether the object's identifier should be retained.</param> /// <param name="headerFields">Other header fields that need to be included.</param> /// <returns>Response.</returns> private static string RequestWithPayload(RequestMethod requestMethod, string url, AuthorisationToken authorisationToken, string body, ServiceType?serviceType = null, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null, bool?mustUseAdvisory = null, NameValueCollection headerFields = null) { HttpWebRequest request = CreateHttpWebRequest(requestMethod, url, authorisationToken, serviceType, null, null, methodOverride, contentTypeOverride, acceptOverride, mustUseAdvisory, headerFields); using (Stream requestStream = request.GetRequestStream()) { if (body != null) { byte[] payload = Encoding.UTF8.GetBytes(body); requestStream.Write(payload, 0, payload.Length); } using (WebResponse response = request.GetResponse()) { string responseString = null; if (response != null) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { responseString = reader.ReadToEnd().Trim(); } } return(responseString); } } }
/// <summary> /// Make a POST request. /// </summary> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="methodOverride">The method that can be used to override the POST, e.g. to issue a GET with a payload.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="mustUseAdvisory">Flag to indicate whether the object's identifier should be retained.</param> /// <param name="requestHeaders">Other header fields that need to be included.</param> /// <returns>Response.</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> public static string PostRequest(string url, AuthorisationToken authorisationToken, string body, ServiceType serviceType = ServiceType.OBJECT, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null, bool?mustUseAdvisory = null, NameValueCollection requestHeaders = null) { WebHeaderCollection responseHeaders; return(MakeRequest(RequestMethod.POST, url, authorisationToken, out responseHeaders, body: body, serviceType: serviceType, methodOverride: methodOverride, contentTypeOverride: contentTypeOverride, acceptOverride: acceptOverride, mustUseAdvisory: mustUseAdvisory, requestHeaders: requestHeaders)); }
public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null) { var eventService = Service as IEventService <TMultiple>; bool eventsSupported = (eventService != null); if (!eventsSupported) { return(BadRequest("Support for SIF Events has not been implemented.")); } IHttpActionResult result; try { IRegistrationService registrationService = RegistrationManager.GetProviderRegistrationService( ProviderSettings, sessionService); if (registrationService is NoRegistrationService) { result = BadRequest("SIF Events are only supported in a BROKERED environment."); } else { IEventIterator <TMultiple> eventIterator = eventService.GetEventIterator(zoneId, contextId); if (eventIterator == null) { result = BadRequest("SIF Events implementation is not valid."); } else { Model.Infrastructure.Environment environment = registrationService.Register(); // Retrieve the current Authorisation Token. AuthorisationToken token = registrationService.AuthorisationToken; // Retrieve the EventsConnector endpoint URL. string url = EnvironmentUtils.ParseServiceUrl( environment, ServiceType.UTILITY, InfrastructureServiceNames.eventsConnector); while (eventIterator.HasNext()) { SifEvent <TMultiple> sifEvent = eventIterator.GetNext(); var requestHeaders = new NameValueCollection() { { EventParameterType.eventAction.ToDescription(), sifEvent.EventAction.ToDescription() }, { EventParameterType.messageId.ToDescription(), sifEvent.Id.ToString() }, { EventParameterType.messageType.ToDescription(), "EVENT" }, { EventParameterType.serviceName.ToDescription(), $"{TypeName}s" } }; switch (sifEvent.EventAction) { case EventAction.UPDATE_FULL: requestHeaders.Add(EventParameterType.Replacement.ToDescription(), "FULL"); break; case EventAction.UPDATE_PARTIAL: requestHeaders.Add(EventParameterType.Replacement.ToDescription(), "PARTIAL"); break; } string requestBody = SerialiseEvents(sifEvent.SifObjects); HttpUtils.PostRequest( url, token, requestBody, ProviderSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), requestHeaders: requestHeaders); } result = Ok(); } } } catch (Exception e) { result = InternalServerError(e); } return(result); }
/// <summary> /// Create a HTTP web request. /// </summary> /// <param name="requestMethod">Request method, e.g. GET.</param> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="compressPayload">Compress payload flag.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="methodOverride">Overrides the method of the request, e.g. to implement a GET with a payload over a POST request.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="mustUseAdvisory">Flag to indicate whether the object's identifier should be retained.</param> /// <param name="deleteMessageId">Unique identifier of the SIF Event message to delete.</param> /// <param name="requestHeaders">Other header fields that need to be included.</param> /// <returns>HTTP web request.</returns> private static HttpWebRequest CreateHttpWebRequest(RequestMethod requestMethod, string url, AuthorisationToken authorisationToken, bool compressPayload, ServiceType?serviceType = null, int?navigationPage = null, int?navigationPageSize = null, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null, bool?mustUseAdvisory = null, string deleteMessageId = null, NameValueCollection requestHeaders = null) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = "application/xml"; request.Method = requestMethod.ToString(); request.KeepAlive = false; request.Accept = "application/xml"; request.Headers.Add("Authorization", authorisationToken.Token); request.Headers.Add("timestamp", authorisationToken.Timestamp ?? DateTime.UtcNow.ToString("o")); if (compressPayload) { request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); } if (serviceType.HasValue) { request.Headers.Add("serviceType", serviceType.Value.ToDescription()); } if (navigationPage.HasValue) { request.Headers.Add("navigationPage", navigationPage.Value.ToString()); } if (navigationPageSize.HasValue) { request.Headers.Add("navigationPageSize", navigationPageSize.Value.ToString()); } if (!string.IsNullOrWhiteSpace(methodOverride)) { request.Headers.Add("X-HTTP-Method-Override", methodOverride.Trim()); } if (!string.IsNullOrWhiteSpace(methodOverride)) { request.Headers.Add("methodOverride", methodOverride.Trim()); } if (!string.IsNullOrWhiteSpace(deleteMessageId)) { request.Headers.Add(RequestHeader.deleteMessageId.ToDescription(), deleteMessageId.Trim()); } if (!string.IsNullOrWhiteSpace(acceptOverride)) { request.Accept = acceptOverride.Trim(); } if (!string.IsNullOrWhiteSpace(contentTypeOverride)) { request.ContentType = contentTypeOverride.Trim(); } if (mustUseAdvisory.HasValue) { request.Headers.Add(RequestHeader.mustUseAdvisory.ToDescription(), mustUseAdvisory.Value.ToString()); } if (requestHeaders != null) { foreach (string name in requestHeaders) { if (!string.IsNullOrWhiteSpace(name)) { string value = requestHeaders[name]; if (!string.IsNullOrWhiteSpace(value)) { request.Headers.Add(name.Trim(), value.Trim()); } } } } return(request); }
/// <summary> /// <see cref="IRegistrationService.Register(ref Environment)">Register</see> /// </summary> public Environment Register(ref Environment environment) { if (Registered) { return(CurrentEnvironment); } if (sessionService.HasSession( environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId)) { if (log.IsDebugEnabled) { log.Debug("Session token already exists for this object service (Consumer/Provider)."); } string storedSessionToken = sessionService.RetrieveSessionToken( environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId); authorisationToken = authorisationTokenService.Generate(storedSessionToken, settings.SharedSecret); string storedEnvironmentUrl = sessionService.RetrieveEnvironmentUrl( environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId); string environmentBody = HttpUtils.GetRequest( storedEnvironmentUrl, authorisationToken, settings.CompressPayload, contentTypeOverride: settings.ContentType.ToDescription(), acceptOverride: settings.Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug($"Environment response from GET request ...\n{environmentBody}"); } environmentType environmentTypeToDeserialise = SerialiserFactory.GetSerialiser <environmentType>(settings.Accept).Deserialise(environmentBody); Environment environmentResponse = MapperFactory.CreateInstance <environmentType, Environment>(environmentTypeToDeserialise); sessionToken = environmentResponse.SessionToken; environmentUrl = environmentResponse.InfrastructureServices[InfrastructureServiceNames.environment].Value; if (log.IsDebugEnabled) { log.Debug($"Environment URL is {environmentUrl}."); } if (!storedSessionToken.Equals(sessionToken) || !storedEnvironmentUrl.Equals(environmentUrl)) { authorisationToken = authorisationTokenService.Generate(sessionToken, settings.SharedSecret); sessionService.RemoveSession(storedSessionToken); sessionService.StoreSession( environmentResponse.ApplicationInfo.ApplicationKey, sessionToken, environmentUrl, environmentResponse.SolutionId, environmentResponse.UserToken, environmentResponse.InstanceId); } environment = environmentResponse; } else { if (log.IsDebugEnabled) { log.Debug("Session token does not exist for this object service (Consumer/Provider)."); } string environmentBody = null; try { AuthorisationToken initialToken = authorisationTokenService.Generate( environment.ApplicationInfo.ApplicationKey, settings.SharedSecret); environmentType environmentTypeToSerialise = MapperFactory.CreateInstance <Environment, environmentType>(environment); string body = SerialiserFactory.GetSerialiser <environmentType>(settings.ContentType) .Serialise(environmentTypeToSerialise); environmentBody = HttpUtils.PostRequest( settings.EnvironmentUrl, initialToken, body, settings.CompressPayload, contentTypeOverride: settings.ContentType.ToDescription(), acceptOverride: settings.Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug($"Environment response from POST request ...\n{environmentBody}"); } environmentType environmentTypeToDeserialise = SerialiserFactory.GetSerialiser <environmentType>(settings.Accept).Deserialise(environmentBody); Environment environmentResponse = MapperFactory.CreateInstance <environmentType, Environment>(environmentTypeToDeserialise); sessionToken = environmentResponse.SessionToken; environmentUrl = environmentResponse.InfrastructureServices[InfrastructureServiceNames.environment].Value; if (log.IsDebugEnabled) { log.Debug($"Environment URL is {environmentUrl}."); } authorisationToken = authorisationTokenService.Generate(sessionToken, settings.SharedSecret); sessionService.StoreSession( environment.ApplicationInfo.ApplicationKey, sessionToken, environmentUrl, environmentResponse.SolutionId, environmentResponse.UserToken, environmentResponse.InstanceId); environment = environmentResponse; } catch (Exception e) { if (environmentUrl != null) { HttpUtils.DeleteRequest(environmentUrl, authorisationToken, settings.CompressPayload); } else if (!string.IsNullOrWhiteSpace(TryParseEnvironmentUrl(environmentBody))) { HttpUtils.DeleteRequest( TryParseEnvironmentUrl(environmentBody), authorisationToken, settings.CompressPayload); } throw new RegistrationException("Registration failed.", e); } } CurrentEnvironment = environment; Registered = true; return(CurrentEnvironment); }
public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null) { IEventService <TMultiple> eventService = service as IEventService <TMultiple>; bool eventsSupported = (eventService != null); if (!eventsSupported) { return(BadRequest("Support for SIF Events has not been implemented.")); } IHttpActionResult result; try { IRegistrationService registrationService = RegistrationManager.ProviderRegistrationService; if (registrationService is NoRegistrationService) { result = BadRequest("SIF Events are only supported in a BROKERED environment."); } else { IEventIterator <TMultiple> eventIterator = eventService.GetEventIterator(zoneId, contextId); if (eventIterator == null) { result = BadRequest("SIF Events implementation is not valid."); } else { // Retrieve the current Authorisation Token. registrationService.Register(); AuthorisationToken token = registrationService.AuthorisationToken; // Retrieve the EventsConnector endpoint URL. Environment environmentTemplate = EnvironmentUtils.LoadFromSettings(SettingsManager.ProviderSettings); string storedSessionToken = SessionsManager.ProviderSessionService.RetrieveSessionToken( environmentTemplate.ApplicationInfo.ApplicationKey, environmentTemplate.SolutionId, environmentTemplate.UserToken, environmentTemplate.InstanceId); Environment environment = authService.GetEnvironmentBySessionToken(storedSessionToken); string url = EnvironmentUtils.ParseServiceUrl(environment, ServiceType.UTILITY, InfrastructureServiceNames.eventsConnector) + "/" + TypeName + "s"; while (eventIterator.HasNext()) { SifEvent <TMultiple> sifEvent = eventIterator.GetNext(); NameValueCollection headerFields = new NameValueCollection() { { HttpUtils.RequestHeader.eventAction.ToDescription(), sifEvent.EventAction.ToDescription() }, { HttpUtils.RequestHeader.messageId.ToDescription(), sifEvent.Id.ToString() }, { HttpUtils.RequestHeader.messageType.ToDescription(), "EVENT" }, { HttpUtils.RequestHeader.serviceName.ToDescription(), $"{TypeName}s" } }; switch (sifEvent.EventAction) { case EventAction.UPDATE_FULL: headerFields.Add(HttpUtils.RequestHeader.Replacement.ToDescription(), "FULL"); break; case EventAction.UPDATE_PARTIAL: headerFields.Add(HttpUtils.RequestHeader.Replacement.ToDescription(), "PARTIAL"); break; } string body = SerialiseEvents(sifEvent.SifObjects); string xml = HttpUtils.PostRequest(url, token, body, headerFields: headerFields); } } result = Ok(); } } catch (Exception e) { result = InternalServerError(e); } return(result); }
/// <summary> /// Create a HTTP web request. /// </summary> /// <param name="requestMethod">Request method, e.g. GET.</param> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="methodOverride">Overrides the method of the request, e.g. to implement a GET with a payload over a POST request.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <returns>HTTP web request.</returns> private static HttpWebRequest CreateHttpWebRequest(RequestMethod requestMethod, string url, AuthorisationToken authorisationToken, ServiceType?serviceType = null, int?navigationPage = null, int?navigationPageSize = null, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = "application/xml"; request.Method = requestMethod.ToString(); request.KeepAlive = false; request.Accept = "application/xml"; request.Headers.Add("Authorization", authorisationToken.Token); request.Headers.Add("timestamp", authorisationToken.Timestamp); if (SettingsManager.ConsumerSettings.CompressPayload) { request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); } if (serviceType.HasValue) { request.Headers.Add("serviceType", serviceType.Value.ToDescription()); } if (navigationPage.HasValue) { request.Headers.Add("navigationPage", navigationPage.Value.ToString()); } if (navigationPageSize.HasValue) { request.Headers.Add("navigationPageSize", navigationPageSize.Value.ToString()); } if (!string.IsNullOrWhiteSpace(methodOverride)) { request.Headers.Add("X-HTTP-Method-Override", methodOverride.Trim()); } if (!string.IsNullOrWhiteSpace(methodOverride)) { request.Headers.Add("methodOverride", methodOverride.Trim()); } if (!string.IsNullOrWhiteSpace(acceptOverride)) { request.Accept = acceptOverride.Trim(); } if (!string.IsNullOrWhiteSpace(contentTypeOverride)) { request.ContentType = contentTypeOverride.Trim(); } return(request); }
/// <summary> /// Make a HTTP request (with or without a payload). /// </summary> /// <param name="requestMethod">Request method, e.g. GET.</param> /// <param name="url">Request endpoint.</param> /// <param name="authorisationToken">The authorization token.</param> /// <param name="compressPayload">Compress payload flag.</param> /// <param name="responseHeaders">Response headers returned.</param> /// <param name="body">The data payload to send.</param> /// <param name="serviceType">Service type.</param> /// <param name="navigationPage">Current paging index.</param> /// <param name="navigationPageSize">Page size.</param> /// <param name="methodOverride">Overrides the method of the request, e.g. to implement a GET with a payload over a POST request.</param> /// <param name="contentTypeOverride">Overrides the ContentType header.</param> /// <param name="acceptOverride">Overrides the Accept header.</param> /// <param name="mustUseAdvisory">Flag to indicate whether the object's identifier should be retained.</param> /// <param name="deleteMessageId">Unique identifier of the SIF Event message to delete.</param> /// <param name="requestHeaders">Other header fields that need to be included.</param> /// <returns>Response (with headers).</returns> /// <exception cref="AuthenticationException">Request is not authorised (authentication failed).</exception> /// <exception cref="UnauthorizedAccessException">Request is forbidden (access denied).</exception> /// <exception cref="Exception">Unexpected error occurred.</exception> private static string MakeRequest(RequestMethod requestMethod, string url, AuthorisationToken authorisationToken, bool compressPayload, out WebHeaderCollection responseHeaders, string body = null, ServiceType?serviceType = null, int?navigationPage = null, int?navigationPageSize = null, string methodOverride = null, string contentTypeOverride = null, string acceptOverride = null, bool?mustUseAdvisory = null, string deleteMessageId = null, NameValueCollection requestHeaders = null) { HttpWebRequest request = CreateHttpWebRequest(requestMethod, url, authorisationToken, compressPayload, serviceType, navigationPage, navigationPageSize, methodOverride, contentTypeOverride, acceptOverride, mustUseAdvisory, deleteMessageId, requestHeaders); try { if (body == null) { using (WebResponse response = request.GetResponse()) { responseHeaders = response.Headers; string responseString = null; if (response != null) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { responseString = reader.ReadToEnd().Trim(); } } return(responseString); } } else { using (Stream requestStream = request.GetRequestStream()) { byte[] payload = Encoding.UTF8.GetBytes(body); requestStream.Write(payload, 0, payload.Length); using (WebResponse response = request.GetResponse()) { responseHeaders = response.Headers; string responseString = null; if (response != null) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { responseString = reader.ReadToEnd().Trim(); } } return(responseString); } } } } catch (Exception e) { if ((e is WebException) && ((WebException)e).Response is HttpWebResponse) { HttpWebResponse httpWebResponse = ((WebException)e).Response as HttpWebResponse; if (httpWebResponse.StatusCode.Equals(HttpStatusCode.Unauthorized)) { throw new AuthenticationException("Request is not authorised (authentication failed).", e); } else if (httpWebResponse.StatusCode.Equals(HttpStatusCode.Forbidden)) { throw new UnauthorizedAccessException("Request is forbidden (access denied).", e); } } throw e; } }
/// <summary> /// <see cref="IAuthorisationTokenService.Verify(AuthorisationToken, GetSharedSecret, out string)"/> /// </summary> public bool Verify(AuthorisationToken authorisationToken, GetSharedSecret getSharedSecret, out string sessionToken) { if (authorisationToken == null) { throw new InvalidAuthorisationTokenException("Authorisation token is null."); } if (string.IsNullOrWhiteSpace(authorisationToken.Token)) { throw new InvalidAuthorisationTokenException("The authorisation token value is null or empty."); } if (string.IsNullOrWhiteSpace(authorisationToken.Timestamp)) { throw new InvalidAuthorisationTokenException("The authorisation token timestamp is null or empty."); } //if (!DateTime.TryParse(authorisationToken.Timestamp, out DateTime tokenTimestamp)) //{ // throw new InvalidAuthorisationTokenException("The authorisation token timestamp is not of a valid format."); //} //TimeSpan timeSpan = DateTime.UtcNow - tokenTimestamp; // TODO: Retrieve the token expiry limit from configuration. //if (timeSpan.TotalSeconds > 10) //{ // throw new InvalidAuthorisationTokenException("The authorisation token timestamp has expired."); //} if (getSharedSecret == null) { throw new ArgumentNullException("getSharedSecret"); } string[] tokens = authorisationToken.Token.Split(' '); if (tokens.Length != 2 || !AuthenticationMethod.SIF_HMACSHA256.ToString().Equals(tokens[0]) || string.IsNullOrWhiteSpace(tokens[1])) { throw new InvalidAuthorisationTokenException("Authorisation token is not recognised."); } string base64EncodedString = tokens[1]; string combinedMessage = Encoding.ASCII.GetString(Convert.FromBase64String(base64EncodedString)); string[] nextTokens = combinedMessage.Split(':'); if (nextTokens.Length != 2 || string.IsNullOrWhiteSpace(nextTokens[0]) || string.IsNullOrWhiteSpace(nextTokens[1])) { throw new InvalidAuthorisationTokenException("Authorisation token is invalid."); } string hmacsha256EncodedString = nextTokens[1]; sessionToken = nextTokens[0]; string sharedSecret = getSharedSecret(sessionToken); // Recalculate the encoded HMAC SHA256 string. // NOTE: Currently there are no checks for the date to be in UTC ISO 8601 format. byte[] messageBytes = Encoding.ASCII.GetBytes(sessionToken + ":" + authorisationToken.Timestamp); byte[] keyBytes = Encoding.ASCII.GetBytes(sharedSecret); string newHmacsha256EncodedString; using (HMACSHA256 hmacsha256 = new HMACSHA256(keyBytes)) { byte[] hashMessage = hmacsha256.ComputeHash(messageBytes); newHmacsha256EncodedString = Convert.ToBase64String(hashMessage); } return(hmacsha256EncodedString.Equals(newHmacsha256EncodedString)); }
/// <summary> /// <see cref="IRegistrationService.Register(ref Environment)">Register</see> /// </summary> public Environment Register(ref Environment environment) { if (Registered) { return(CurrentEnvironment); } if (sessionService.HasSession(environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId)) { if (log.IsDebugEnabled) { log.Debug("Session token already exists for this object service (Consumer/Provider)."); } string storedSessionToken = sessionService.RetrieveSessionToken(environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId); AuthorisationToken = authorisationTokenService.Generate(storedSessionToken, settings.SharedSecret); string storedEnvironmentUrl = sessionService.RetrieveEnvironmentUrl(environment.ApplicationInfo.ApplicationKey, environment.SolutionId, environment.UserToken, environment.InstanceId); string environmentXml = HttpUtils.GetRequest(storedEnvironmentUrl, AuthorisationToken); if (log.IsDebugEnabled) { log.Debug("Environment XML from GET request ..."); } if (log.IsDebugEnabled) { log.Debug(environmentXml); } environmentType environmentTypeToDeserialise = SerialiserFactory.GetXmlSerialiser <environmentType>().Deserialise(environmentXml); Environment environmentResponse = MapperFactory.CreateInstance <environmentType, Environment>(environmentTypeToDeserialise); sessionToken = environmentResponse.SessionToken; environmentUrl = environmentResponse.InfrastructureServices[InfrastructureServiceNames.environment].Value; if (log.IsDebugEnabled) { log.Debug("Environment URL is " + environmentUrl + "."); } if (!storedSessionToken.Equals(sessionToken) || !storedEnvironmentUrl.Equals(environmentUrl)) { AuthorisationToken = authorisationTokenService.Generate(sessionToken, settings.SharedSecret); sessionService.RemoveSession(storedSessionToken); sessionService.StoreSession(environmentResponse.ApplicationInfo.ApplicationKey, sessionToken, environmentUrl, environmentResponse.SolutionId, environmentResponse.UserToken, environmentResponse.InstanceId); } environment = environmentResponse; } else { if (log.IsDebugEnabled) { log.Debug("Session token does not exist for this object service (Consumer/Provider)."); } AuthorisationToken initialToken = authorisationTokenService.Generate(environment.ApplicationInfo.ApplicationKey, settings.SharedSecret); environmentType environmentTypeToSerialise = MapperFactory.CreateInstance <Environment, environmentType>(environment); string body = SerialiserFactory.GetXmlSerialiser <environmentType>().Serialise(environmentTypeToSerialise); string environmentXml = HttpUtils.PostRequest(settings.EnvironmentUrl, initialToken, body); if (log.IsDebugEnabled) { log.Debug("Environment XML from POST request ..."); } if (log.IsDebugEnabled) { log.Debug(environmentXml); } try { environmentType environmentTypeToDeserialise = SerialiserFactory.GetXmlSerialiser <environmentType>().Deserialise(environmentXml); Environment environmentResponse = MapperFactory.CreateInstance <environmentType, Environment>(environmentTypeToDeserialise); sessionToken = environmentResponse.SessionToken; environmentUrl = environmentResponse.InfrastructureServices[InfrastructureServiceNames.environment].Value; if (log.IsDebugEnabled) { log.Debug("Environment URL is " + environmentUrl + "."); } AuthorisationToken = authorisationTokenService.Generate(sessionToken, settings.SharedSecret); sessionService.StoreSession(environment.ApplicationInfo.ApplicationKey, sessionToken, environmentUrl, environmentResponse.SolutionId, environmentResponse.UserToken, environmentResponse.InstanceId); environment = environmentResponse; } catch (Exception) { if (environmentUrl != null) { HttpUtils.DeleteRequest(environmentUrl, AuthorisationToken); } else if (!string.IsNullOrWhiteSpace(TryParseEnvironmentUrl(environmentXml))) { HttpUtils.DeleteRequest(TryParseEnvironmentUrl(environmentXml), AuthorisationToken); } throw; } } CurrentEnvironment = environment; Registered = true; return(CurrentEnvironment); }