HubWithPreAuthorizationSample.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #if !BESTHTTP_DISABLE_SIGNALR_CORE
  2. using BestHTTP;
  3. using BestHTTP.Connections;
  4. using BestHTTP.Examples.Helpers;
  5. using BestHTTP.SignalRCore;
  6. using BestHTTP.SignalRCore.Encoders;
  7. using System;
  8. using UnityEngine;
  9. using UnityEngine.UI;
  10. namespace BestHTTP.Examples
  11. {
  12. public sealed class HubWithPreAuthorizationSample : BestHTTP.Examples.Helpers.SampleBase
  13. {
  14. #pragma warning disable 0649
  15. [SerializeField]
  16. private string _hubPath = "/HubWithAuthorization";
  17. [SerializeField]
  18. private string _jwtTokenPath = "/generateJwtToken";
  19. [SerializeField]
  20. private ScrollRect _scrollRect;
  21. [SerializeField]
  22. private RectTransform _contentRoot;
  23. [SerializeField]
  24. private TextListItem _listItemPrefab;
  25. [SerializeField]
  26. private int _maxListItemEntries = 100;
  27. [SerializeField]
  28. private Button _connectButton;
  29. [SerializeField]
  30. private Button _closeButton;
  31. #pragma warning restore
  32. // Instance of the HubConnection
  33. HubConnection hub;
  34. protected override void Start()
  35. {
  36. base.Start();
  37. SetButtons(true, false);
  38. }
  39. void OnDestroy()
  40. {
  41. if (hub != null)
  42. hub.StartClose();
  43. }
  44. public void OnConnectButton()
  45. {
  46. // Server side of this example can be found here:
  47. // https://github.com/Benedicht/BestHTTP_DemoSite/blob/master/BestHTTP_DemoSite/Hubs/
  48. #if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
  49. try
  50. {
  51. MessagePack.Resolvers.StaticCompositeResolver.Instance.Register(
  52. MessagePack.Resolvers.DynamicEnumAsStringResolver.Instance,
  53. MessagePack.Unity.UnityResolver.Instance,
  54. //MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
  55. //MessagePack.Resolvers.StandardResolver.Instance,
  56. MessagePack.Resolvers.ContractlessStandardResolver.Instance
  57. );
  58. var options = MessagePack.MessagePackSerializerOptions.Standard.WithResolver(MessagePack.Resolvers.StaticCompositeResolver.Instance);
  59. MessagePack.MessagePackSerializer.DefaultOptions = options;
  60. }
  61. catch
  62. { }
  63. #endif
  64. IProtocol protocol = null;
  65. #if BESTHTTP_SIGNALR_CORE_ENABLE_MESSAGEPACK_CSHARP
  66. protocol = new MessagePackCSharpProtocol();
  67. #elif BESTHTTP_SIGNALR_CORE_ENABLE_GAMEDEVWARE_MESSAGEPACK
  68. protocol = new MessagePackProtocol();
  69. #else
  70. protocol = new JsonProtocol(new LitJsonEncoder());
  71. #endif
  72. // Crete the HubConnection
  73. hub = new HubConnection(new Uri(base.sampleSelector.BaseURL + this._hubPath), protocol);
  74. hub.AuthenticationProvider = new PreAuthAccessTokenAuthenticator(new Uri(base.sampleSelector.BaseURL + this._jwtTokenPath));
  75. hub.AuthenticationProvider.OnAuthenticationSucceded += AuthenticationProvider_OnAuthenticationSucceded;
  76. hub.AuthenticationProvider.OnAuthenticationFailed += AuthenticationProvider_OnAuthenticationFailed;
  77. // Subscribe to hub events
  78. hub.OnConnected += Hub_OnConnected;
  79. hub.OnError += Hub_OnError;
  80. hub.OnClosed += Hub_OnClosed;
  81. hub.OnTransportEvent += (hub, transport, ev) => AddText(string.Format("Transport(<color=green>{0}</color>) event: <color=green>{1}</color>", transport.TransportType, ev));
  82. // And finally start to connect to the server
  83. hub.StartConnect();
  84. AddText("StartConnect called");
  85. SetButtons(false, false);
  86. }
  87. public void OnCloseButton()
  88. {
  89. if (hub != null)
  90. {
  91. hub.StartClose();
  92. AddText("StartClose called");
  93. SetButtons(false, false);
  94. }
  95. }
  96. private void AuthenticationProvider_OnAuthenticationSucceded(IAuthenticationProvider provider)
  97. {
  98. string str = string.Format("Pre-Authentication Succeded! Token: '<color=green>{0}</color>' ", (hub.AuthenticationProvider as PreAuthAccessTokenAuthenticator).Token);
  99. AddText(str);
  100. }
  101. private void AuthenticationProvider_OnAuthenticationFailed(IAuthenticationProvider provider, string reason)
  102. {
  103. AddText(string.Format("Authentication Failed! Reason: '{0}'", reason));
  104. }
  105. /// <summary>
  106. /// This callback is called when the plugin is connected to the server successfully. Messages can be sent to the server after this point.
  107. /// </summary>
  108. private void Hub_OnConnected(HubConnection hub)
  109. {
  110. AddText(string.Format("Hub Connected with <color=green>{0}</color> transport using the <color=green>{1}</color> encoder.", hub.Transport.TransportType.ToString(), hub.Protocol.Name));
  111. SetButtons(false, true);
  112. // Call a parameterless function. We expect a string return value.
  113. hub.Invoke<string>("Echo", "Message from the client")
  114. .OnSuccess(ret => AddText(string.Format("'<color=green>Echo</color>' returned: '<color=yellow>{0}</color>'", ret)).AddLeftPadding(20));
  115. AddText("'<color=green>Message from the client</color>' sent!")
  116. .AddLeftPadding(20);
  117. }
  118. /// <summary>
  119. /// This is called when the hub is closed after a StartClose() call.
  120. /// </summary>
  121. private void Hub_OnClosed(HubConnection hub)
  122. {
  123. AddText("Hub Closed");
  124. SetButtons(true, false);
  125. }
  126. /// <summary>
  127. /// Called when an unrecoverable error happen. After this event the hub will not send or receive any messages.
  128. /// </summary>
  129. private void Hub_OnError(HubConnection hub, string error)
  130. {
  131. AddText(string.Format("Hub Error: <color=red>{0}</color>", error));
  132. SetButtons(true, false);
  133. }
  134. private void SetButtons(bool connect, bool close)
  135. {
  136. if (this._connectButton != null)
  137. this._connectButton.interactable = connect;
  138. if (this._closeButton != null)
  139. this._closeButton.interactable = close;
  140. }
  141. private TextListItem AddText(string text)
  142. {
  143. return GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
  144. }
  145. }
  146. public sealed class PreAuthAccessTokenAuthenticator : IAuthenticationProvider
  147. {
  148. /// <summary>
  149. /// No pre-auth step required for this type of authentication
  150. /// </summary>
  151. public bool IsPreAuthRequired { get { return true; } }
  152. #pragma warning disable 0067
  153. /// <summary>
  154. /// Not used event as IsPreAuthRequired is false
  155. /// </summary>
  156. public event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;
  157. /// <summary>
  158. /// Not used event as IsPreAuthRequired is false
  159. /// </summary>
  160. public event OnAuthenticationFailedDelegate OnAuthenticationFailed;
  161. #pragma warning restore 0067
  162. public string Token { get; private set; }
  163. private Uri authenticationUri;
  164. private HTTPRequest authenticationRequest;
  165. private bool isCancellationRequested;
  166. public PreAuthAccessTokenAuthenticator(Uri authUri)
  167. {
  168. this.authenticationUri = authUri;
  169. }
  170. public void StartAuthentication()
  171. {
  172. this.authenticationRequest = new HTTPRequest(this.authenticationUri, OnAuthenticationRequestFinished);
  173. this.authenticationRequest.Send();
  174. }
  175. private void OnAuthenticationRequestFinished(HTTPRequest req, HTTPResponse resp)
  176. {
  177. switch (req.State)
  178. {
  179. // The request finished without any problem.
  180. case HTTPRequestStates.Finished:
  181. if (resp.IsSuccess)
  182. {
  183. this.authenticationRequest = null;
  184. this.Token = resp.DataAsText;
  185. if (this.OnAuthenticationSucceded != null)
  186. this.OnAuthenticationSucceded(this);
  187. }
  188. else // Internal server error?
  189. AuthenticationFailed(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
  190. resp.StatusCode,
  191. resp.Message,
  192. resp.DataAsText));
  193. break;
  194. // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
  195. case HTTPRequestStates.Error:
  196. AuthenticationFailed("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "" + req.Exception.StackTrace) : "No Exception"));
  197. break;
  198. // The request aborted, initiated by the user.
  199. case HTTPRequestStates.Aborted:
  200. AuthenticationFailed("Request Aborted!");
  201. break;
  202. // Connecting to the server is timed out.
  203. case HTTPRequestStates.ConnectionTimedOut:
  204. AuthenticationFailed("Connection Timed Out!");
  205. break;
  206. // The request didn't finished in the given time.
  207. case HTTPRequestStates.TimedOut:
  208. AuthenticationFailed("Processing the request Timed Out!");
  209. break;
  210. }
  211. }
  212. private void AuthenticationFailed(string reason)
  213. {
  214. this.authenticationRequest = null;
  215. if (this.isCancellationRequested)
  216. return;
  217. if (this.OnAuthenticationFailed != null)
  218. this.OnAuthenticationFailed(this, reason);
  219. }
  220. /// <summary>
  221. /// Prepares the request by adding two headers to it
  222. /// </summary>
  223. public void PrepareRequest(BestHTTP.HTTPRequest request)
  224. {
  225. if (HTTPProtocolFactory.GetProtocolFromUri(request.CurrentUri) == SupportedProtocols.HTTP)
  226. request.Uri = PrepareUri(request.Uri);
  227. }
  228. public Uri PrepareUri(Uri uri)
  229. {
  230. if (!string.IsNullOrEmpty(this.Token))
  231. {
  232. string query = string.IsNullOrEmpty(uri.Query) ? "?" : uri.Query + "&";
  233. UriBuilder uriBuilder = new UriBuilder(uri.Scheme, uri.Host, uri.Port, uri.AbsolutePath, query + "access_token=" + this.Token);
  234. return uriBuilder.Uri;
  235. }
  236. else
  237. return uri;
  238. }
  239. public void Cancel()
  240. {
  241. this.isCancellationRequested = true;
  242. if (this.authenticationRequest != null)
  243. this.authenticationRequest.Abort();
  244. }
  245. }
  246. }
  247. #endif