HubWithPreAuthorizationSample.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #if !BESTHTTP_DISABLE_SIGNALR_CORE
  2. using BestHTTP;
  3. using BestHTTP.SignalRCore;
  4. using BestHTTP.SignalRCore.Encoders;
  5. using System;
  6. using UnityEngine;
  7. namespace BestHTTP.Examples
  8. {
  9. public sealed class HubWithPreAuthorizationSample : MonoBehaviour
  10. {
  11. // Server uri to connect to
  12. readonly Uri URI = new Uri(GUIHelper.BaseURL + "/HubWithAuthorization");
  13. readonly Uri AuthURI = new Uri(GUIHelper.BaseURL + "/generateJwtToken");
  14. // Instance of the HubConnection
  15. HubConnection hub;
  16. Vector2 scrollPos;
  17. string uiText;
  18. void Start()
  19. {
  20. // Server side of this example can be found here:
  21. // https://github.com/Benedicht/BestHTTP_DemoSite/blob/master/BestHTTP_DemoSite/Hubs/
  22. // Crete the HubConnection
  23. hub = new HubConnection(URI, new JsonProtocol(new LitJsonEncoder()));
  24. hub.AuthenticationProvider = new PreAuthAccessTokenAuthenticator(AuthURI);
  25. hub.AuthenticationProvider.OnAuthenticationSucceded += AuthenticationProvider_OnAuthenticationSucceded;
  26. hub.AuthenticationProvider.OnAuthenticationFailed += AuthenticationProvider_OnAuthenticationFailed;
  27. // Subscribe to hub events
  28. hub.OnConnected += Hub_OnConnected;
  29. hub.OnError += Hub_OnError;
  30. hub.OnClosed += Hub_OnClosed;
  31. hub.OnMessage += Hub_OnMessage;
  32. // And finally start to connect to the server
  33. hub.StartConnect();
  34. uiText = "StartConnect called\n";
  35. }
  36. private void AuthenticationProvider_OnAuthenticationSucceded(IAuthenticationProvider provider)
  37. {
  38. string str = string.Format("Pre-Authentication Succeded! Token: '{0}' \n", (hub.AuthenticationProvider as PreAuthAccessTokenAuthenticator).Token);
  39. Debug.Log(str);
  40. uiText += str;
  41. }
  42. private void AuthenticationProvider_OnAuthenticationFailed(IAuthenticationProvider provider, string reason)
  43. {
  44. uiText += string.Format("Authentication Failed! Reason: '{0}'\n", reason);
  45. }
  46. void OnDestroy()
  47. {
  48. if (hub != null)
  49. hub.StartClose();
  50. }
  51. // Draw the text stored in the 'uiText' field
  52. void OnGUI()
  53. {
  54. GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
  55. {
  56. scrollPos = GUILayout.BeginScrollView(scrollPos, false, false);
  57. GUILayout.BeginVertical();
  58. GUILayout.Label(uiText);
  59. GUILayout.EndVertical();
  60. GUILayout.EndScrollView();
  61. });
  62. }
  63. /// <summary>
  64. /// This callback is called when the plugin is connected to the server successfully. Messages can be sent to the server after this point.
  65. /// </summary>
  66. private void Hub_OnConnected(HubConnection hub)
  67. {
  68. uiText += "Hub Connected\n";
  69. // Call a parameterless function. We expect a string return value.
  70. hub.Invoke<string>("Echo", "Message from the client")
  71. .OnSuccess(ret => uiText += string.Format(" 'Echo' returned: '{0}'\n", ret));
  72. }
  73. /// <summary>
  74. /// This callback is called for every hub message. If false is returned, the plugin will cancel any further processing of the message.
  75. /// </summary>
  76. private bool Hub_OnMessage(HubConnection hub, BestHTTP.SignalRCore.Messages.Message message)
  77. {
  78. //uiText += string.Format("( Message received: {0} )\n", message.ToString());
  79. return true;
  80. }
  81. /// <summary>
  82. /// This is called when the hub is closed after a StartClose() call.
  83. /// </summary>
  84. private void Hub_OnClosed(HubConnection hub)
  85. {
  86. uiText += "Hub Closed\n";
  87. }
  88. /// <summary>
  89. /// Called when an unrecoverable error happen. After this event the hub will not send or receive any messages.
  90. /// </summary>
  91. private void Hub_OnError(HubConnection hub, string error)
  92. {
  93. uiText += "Hub Error: " + error + "\n";
  94. }
  95. }
  96. public sealed class PreAuthAccessTokenAuthenticator : IAuthenticationProvider
  97. {
  98. /// <summary>
  99. /// No pre-auth step required for this type of authentication
  100. /// </summary>
  101. public bool IsPreAuthRequired { get { return true; } }
  102. #pragma warning disable 0067
  103. /// <summary>
  104. /// Not used event as IsPreAuthRequired is false
  105. /// </summary>
  106. public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
  107. /// <summary>
  108. /// Not used event as IsPreAuthRequired is false
  109. /// </summary>
  110. public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
  111. #pragma warning restore 0067
  112. private Uri authenticationUri;
  113. public string Token { get; private set; }
  114. public PreAuthAccessTokenAuthenticator(Uri authUri)
  115. {
  116. this.authenticationUri = authUri;
  117. }
  118. public void StartAuthentication()
  119. {
  120. var request = new HTTPRequest(this.authenticationUri, OnAuthenticationRequestFinished);
  121. request.Send();
  122. }
  123. private void OnAuthenticationRequestFinished(HTTPRequest req, HTTPResponse resp)
  124. {
  125. switch (req.State)
  126. {
  127. // The request finished without any problem.
  128. case HTTPRequestStates.Finished:
  129. if (resp.IsSuccess)
  130. {
  131. this.Token = resp.DataAsText;
  132. if (this.OnAuthenticationSucceded != null)
  133. this.OnAuthenticationSucceded(this);
  134. }
  135. else // Internal server error?
  136. AuthenticationFailed(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
  137. resp.StatusCode,
  138. resp.Message,
  139. resp.DataAsText));
  140. break;
  141. // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
  142. case HTTPRequestStates.Error:
  143. AuthenticationFailed("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
  144. break;
  145. // The request aborted, initiated by the user.
  146. case HTTPRequestStates.Aborted:
  147. AuthenticationFailed("Request Aborted!");
  148. break;
  149. // Connecting to the server is timed out.
  150. case HTTPRequestStates.ConnectionTimedOut:
  151. AuthenticationFailed("Connection Timed Out!");
  152. break;
  153. // The request didn't finished in the given time.
  154. case HTTPRequestStates.TimedOut:
  155. AuthenticationFailed("Processing the request Timed Out!");
  156. break;
  157. }
  158. }
  159. private void AuthenticationFailed(string reason)
  160. {
  161. if (this.OnAuthenticationFailed != null)
  162. this.OnAuthenticationFailed(this, reason);
  163. }
  164. /// <summary>
  165. /// Prepares the request by adding two headers to it
  166. /// </summary>
  167. public void PrepareRequest(BestHTTP.HTTPRequest request)
  168. {
  169. if (HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) == SupportedProtocols.HTTP)
  170. request.Uri = PrepareUri(request.Uri);
  171. }
  172. public Uri PrepareUri(Uri uri)
  173. {
  174. if (!string.IsNullOrEmpty(this.Token))
  175. {
  176. string query = string.IsNullOrEmpty(uri.Query) ? "?" : uri.Query + "&";
  177. UriBuilder uriBuilder = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath, query + "access_token=" + this.Token);
  178. return uriBuilder.Uri;
  179. }
  180. else
  181. return uri;
  182. }
  183. }
  184. }
  185. #endif