From 0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sun, 24 Feb 2019 00:57:14 +0200 Subject: Working on refresh tokens... --- .../Security/RefreshTokenEncoder.cs | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs') diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs new file mode 100644 index 000000000..3948ae1c4 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Tango.Core.Cryptography; + +namespace Tango.MachineService.Security +{ + public class RefreshTokenEncoder + { + public String Encode(T obj) + { + String str = obj.ToJsonString(); + Rfc2898Cryptographer crypt = new Rfc2898Cryptographer(); + return crypt.Encrypt(str); + } + + public T Decode(String token) + { + Rfc2898Cryptographer crypt = new Rfc2898Cryptographer(); + String str = crypt.Decrypt(token); + return JsonConvert.DeserializeObject(str); + } + } +} \ No newline at end of file -- cgit v1.3.1 From 64b768178dc9e64293a52c1b6d2631709af9502a Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 24 Feb 2019 13:38:47 +0200 Subject: Removed all refresh tokens use :/ --- .../Build/Shortcuts/Machine Emulator.lnk | Bin 1530 -> 1445 bytes .../Build/Shortcuts/Machine Studio.lnk | Bin 1581 -> 1516 bytes .../Build/Shortcuts/Proto Compiler GUI.lnk | Bin 1529 -> 1444 bytes .../Build/Shortcuts/Stubs Execution GUI.lnk | Bin 1547 -> 1462 bytes .../Build/Shortcuts/Transport Router.lnk | Bin 1578 -> 1493 bytes .../Properties/AssemblyInfo.cs | 2 +- .../MachineService/MachineStudio_Controller_TST.cs | 2 +- .../Tango.UnitTesting/Web/JWT_Tokens_TST.cs | 2 - .../ExtensionMethods/CloudTableExtensions.cs | 14 +++--- .../Tango.Web/Security/RefreshTokenEntity.cs | 24 --------- .../Tango.Web/Security/RenewTokenRequest.cs | 14 ------ .../Tango.Web/Security/RenewTokenResponse.cs | 14 ------ .../Visual_Studio/Tango.Web/Security/WebToken.cs | 34 +++++++++---- .../Tango.Web/Security/WebTokenResponse.cs | 1 - Software/Visual_Studio/Tango.Web/Tango.Web.csproj | 3 -- Software/Visual_Studio/Tango.Web/TangoWebClient.cs | 21 +------- .../Controllers/MachineStudioController.cs | 21 -------- .../Security/RefreshTokenEncoder.cs | 8 +-- .../Security/RefreshTokenEntity.cs | 55 +++++++++++++++++++++ .../Security/RefreshTokensManager.cs | 16 ++++-- .../Tango.MachineService.csproj | 3 +- 21 files changed, 107 insertions(+), 127 deletions(-) delete mode 100644 Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs delete mode 100644 Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs delete mode 100644 Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEntity.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs') diff --git a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk index 20ad50570..82d25f5cb 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk and b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk b/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk index a1eb6ae58..34b13a9c4 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk and b/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk index 37b68bcf8..2d58f55bf 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk and b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk index 0b46f425e..41d0606ed 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk and b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk differ diff --git a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk index 04c0b9bb2..a4d815d5a 100644 Binary files a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk and b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs index bceaaf956..f313e9073 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs @@ -4,5 +4,5 @@ using System.Runtime.InteropServices; [assembly: System.Windows.ThemeInfo(System.Windows.ResourceDictionaryLocation.None, System.Windows.ResourceDictionaryLocation.SourceAssembly)] [assembly: AssemblyTitle("Tango - Machine Studio")] -[assembly: AssemblyVersion("4.0.7.0")] +[assembly: AssemblyVersion("4.0.9.0")] [assembly: ComVisible(false)] \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.UnitTesting/MachineService/MachineStudio_Controller_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/MachineService/MachineStudio_Controller_TST.cs index 56a57ab92..21ab16307 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/MachineService/MachineStudio_Controller_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/MachineService/MachineStudio_Controller_TST.cs @@ -12,7 +12,7 @@ namespace Tango.UnitTesting.MachineService [TestCategory("Machine Service - Machine Studio")] public class MachineStudio_Controller_TST { - private const string address = "http://localhost:51581"; + private const string address = "http://localhost:1111"; [TestMethod] public void Login_and_check_for_updates() diff --git a/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs index d696a627c..6f97e1c4e 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs @@ -63,7 +63,5 @@ namespace Tango.UnitTesting.Web //Ensure the token validation fails with 'token expired'. Assert.ThrowsException(() => read_web_token.Validate(secret)); } - - } } diff --git a/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs b/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs index 43c4804d3..ffffe6950 100644 --- a/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs +++ b/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs @@ -15,10 +15,10 @@ public static class CloudTableExtensions /// Partition key - i.e., last name /// Row key - i.e., first name /// A Task object - public static async Task GetEntityAsync(this CloudTable table, string partitionKey, string rowKey) where T : class, ITableEntity + public static T GetEntity(this CloudTable table, string partitionKey, string rowKey) where T : class, ITableEntity { TableOperation retrieveOperation = TableOperation.Retrieve(partitionKey, rowKey); - TableResult result = await table.ExecuteAsync(retrieveOperation); + TableResult result = table.Execute(retrieveOperation); T customer = result.Result as T; return customer; } @@ -33,7 +33,7 @@ public static class CloudTableExtensions /// The sample table name /// The entity to insert or merge /// A Task object - public static async Task InsertOrUpdateEntityAsync(this CloudTable table, T entity) where T : class, ITableEntity + public static T InsertOrUpdateEntity(this CloudTable table, T entity) where T : class, ITableEntity { if (entity == null) { @@ -41,10 +41,10 @@ public static class CloudTableExtensions } // Create the InsertOrReplace table operation - TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(entity); + TableOperation insertOrMergeOperation = TableOperation.InsertOrReplace(entity); // Execute the operation. - TableResult result = await table.ExecuteAsync(insertOrMergeOperation); + TableResult result = table.Execute(insertOrMergeOperation); T insertedCustomer = result.Result as T; return insertedCustomer; @@ -56,7 +56,7 @@ public static class CloudTableExtensions /// Sample table name /// Entity to delete /// A Task object - public static async Task DeleteEntityAsync(this CloudTable table, T deleteEntity) where T : class, ITableEntity + public static void DeleteEntity(this CloudTable table, T deleteEntity) where T : class, ITableEntity { if (deleteEntity == null) { @@ -64,6 +64,6 @@ public static class CloudTableExtensions } TableOperation deleteOperation = TableOperation.Delete(deleteEntity); - await table.ExecuteAsync(deleteOperation); + table.Execute(deleteOperation); } } diff --git a/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs b/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs deleted file mode 100644 index 839027ca1..000000000 --- a/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.WindowsAzure.Storage.Table; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Web.Security -{ - public class RefreshTokenEntity : TableEntity - { - /// - /// Initializes a new instance of the class. - /// - public RefreshTokenEntity() - { - - } - - public String RefreshToken { get; set; } - public String AccessToken { get; set; } - public DateTime Expiration { get; set; } - } -} diff --git a/Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs b/Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs deleted file mode 100644 index 213cd3afd..000000000 --- a/Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Transport.Web; - -namespace Tango.Web.Security -{ - public class RenewTokenRequest : WebRequestMessage - { - public String RefreshToken { get; set; } - } -} diff --git a/Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs b/Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs deleted file mode 100644 index 76c381852..000000000 --- a/Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Transport.Web; - -namespace Tango.Web.Security -{ - public class RenewTokenResponse : WebTokenResponse - { - - } -} diff --git a/Software/Visual_Studio/Tango.Web/Security/WebToken.cs b/Software/Visual_Studio/Tango.Web/Security/WebToken.cs index 006ed9de7..7aa4860ab 100644 --- a/Software/Visual_Studio/Tango.Web/Security/WebToken.cs +++ b/Software/Visual_Studio/Tango.Web/Security/WebToken.cs @@ -38,12 +38,15 @@ namespace Tango.Web.Security builder = builder.ExpirationTime(expiration.Value); } + String refreshToken = Guid.NewGuid().ToString(); + builder = builder.AddClaim("object", null); + builder = builder.AddClaim("refresh-token", refreshToken); return new WebToken() { AccessToken = builder.Build(), - RefreshToken = Guid.NewGuid().ToString(), + RefreshToken = refreshToken, Expiration = expiration, Issued = issued, }; @@ -65,11 +68,10 @@ namespace Tango.Web.Security .Decode(AccessToken); } - public WebToken Renew(String secret, String token) + public WebToken Renew(String secret) { - WebToken webToken = WebToken.FromToken(token); - var newToken = CreateNew(secret, DateTime.UtcNow.Add(webToken.Expiration.Value - webToken.Issued)); - newToken.RefreshToken = webToken.RefreshToken; + var newToken = CreateNew(secret, DateTime.UtcNow.Add(Expiration.Value - Issued)); + newToken.RefreshToken = RefreshToken; return newToken; } @@ -95,6 +97,11 @@ namespace Tango.Web.Security webToken.Issued = ConvertEpochToDateTime(iat); } + if (payload.ContainsKey("refresh-token")) + { + webToken.RefreshToken = payload["refresh-token"].ToString(); + } + return webToken; } @@ -128,12 +135,15 @@ namespace Tango.Web.Security builder = builder.ExpirationTime(expiration.Value); } + String refreshToken = Guid.NewGuid().ToString(); + builder = builder.AddClaim("object", obj); + builder = builder.AddClaim("refresh-token", refreshToken); return new WebToken() { AccessToken = builder.Build(), - RefreshToken = Guid.NewGuid().ToString(), + RefreshToken = refreshToken, Expiration = expiration, Issued = issued, Object = obj, @@ -162,16 +172,20 @@ namespace Tango.Web.Security webToken.Issued = ConvertEpochToDateTime(iat); } + if (payload.ContainsKey("refresh-token")) + { + webToken.RefreshToken = payload["refresh-token"].ToString(); + } + webToken.Object = JsonConvert.DeserializeObject(payload["object"].ToString()); return webToken; } - public new WebToken Renew(String secret, String token) + public new WebToken Renew(String secret) { - WebToken webToken = WebToken.FromToken(token); - var newToken = WebToken.CreateNew(secret, webToken.Object, DateTime.UtcNow.Add(webToken.Expiration.Value - webToken.Issued)); - newToken.RefreshToken = webToken.RefreshToken; + var newToken = WebToken.CreateNew(secret, Object, DateTime.UtcNow.Add(Expiration.Value - Issued)); + newToken.RefreshToken = RefreshToken; return newToken; } } diff --git a/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs b/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs index 8c8f2f096..e68305fbb 100644 --- a/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs +++ b/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs @@ -10,6 +10,5 @@ namespace Tango.Web.Security public class WebTokenResponse : WebResponseMessage { public String AccessToken { get; set; } - public String RefreshToken { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj index 621014496..b16473a96 100644 --- a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj +++ b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj @@ -248,9 +248,6 @@ GlobalVersionInfo.cs - - - diff --git a/Software/Visual_Studio/Tango.Web/TangoWebClient.cs b/Software/Visual_Studio/Tango.Web/TangoWebClient.cs index 08fc19099..1d2f9fc8e 100644 --- a/Software/Visual_Studio/Tango.Web/TangoWebClient.cs +++ b/Software/Visual_Studio/Tango.Web/TangoWebClient.cs @@ -70,29 +70,13 @@ namespace Tango.Web return response; } - private async Task Renew() - { - var response = await _client.PostJson(GetActionAddress("Renew"), new RenewTokenRequest() - { - RefreshToken = WebToken.RefreshToken, - }); - - Token = response.AccessToken; - _client.AuthenticationToken = Token; - - WebToken = WebToken.FromToken(Token); - - IsAuthenticated = true; - } - protected virtual async Task Post(String action, TRequest request) where TRequest : class, IWebRequestMessage where TResponse : class, IWebResponseMessage { if (IsAuthenticated) { if (DateTime.UtcNow >= WebToken.Expiration) { - await Renew(); - //await Login(_lastLoginRequest); + await Login(_lastLoginRequest); } } @@ -105,8 +89,7 @@ namespace Tango.Web { try { - //await Login(_lastLoginRequest); - await Renew(); + await Login(_lastLoginRequest); var response = await _client.PostJson(GetActionAddress(action), request); return response; } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs index 324878f25..29cc067d6 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs @@ -366,27 +366,6 @@ namespace Tango.MachineService.Controllers }; } - [HttpPost] - [JwtTokenFilter(allowExpired: true)] - public RenewTokenResponse Renew(RenewTokenRequest request) - { - RefreshTokensManager manager = new RefreshTokensManager(); - var entity = manager.GetToken(request.RefreshToken); - - if (entity.AccessToken != RequestToken.AccessToken) - { - throw new AuthenticationException("Invalid access token and refresh token combination."); - } - - var newToken = RequestToken.Renew(MachineServiceConfig.JWT_TOKEN_SECRET, entity.AccessToken); - - return new RenewTokenResponse() - { - AccessToken = entity.AccessToken, - RefreshToken = entity.RefreshToken, - }; - } - #endregion } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs index 3948ae1c4..896788ffc 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs @@ -11,16 +11,16 @@ namespace Tango.MachineService.Security { public String Encode(T obj) { - String str = obj.ToJsonString(); + String json = JsonConvert.SerializeObject(obj); Rfc2898Cryptographer crypt = new Rfc2898Cryptographer(); - return crypt.Encrypt(str); + return crypt.Encrypt(json); } public T Decode(String token) { Rfc2898Cryptographer crypt = new Rfc2898Cryptographer(); - String str = crypt.Decrypt(token); - return JsonConvert.DeserializeObject(str); + String json = crypt.Decrypt(token); + return JsonConvert.DeserializeObject(json); } } } \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEntity.cs b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEntity.cs new file mode 100644 index 000000000..2788799aa --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEntity.cs @@ -0,0 +1,55 @@ +using Microsoft.WindowsAzure.Storage.Table; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineService.Security +{ + public class RefreshTokenEntity : TableEntity where T : class + { + /// + /// Initializes a new instance of the class. + /// + public RefreshTokenEntity() + { + + } + + + public RefreshTokenEntity(String identity, String accessToken, String refreshToken, DateTime expiration, T obj) + { + PartitionKey = MachineServiceConfig.REFRESH_TOKENS_TABLE_PARTITION; + + Identity = identity; + AccessToken = accessToken; + RefreshToken = refreshToken; + Expiration = expiration; + + RefreshTokenEncoder encoder = new RefreshTokenEncoder(); + Object = encoder.Encode(obj); + } + + [IgnoreProperty] + public String RefreshToken + { + get { return RowKey; } + set { RowKey = value; } + } + + public String Identity { get; set; } + + public String AccessToken { get; set; } + + public DateTime Expiration { get; set; } + + public String Object { get; set; } + + public T GetObject() + { + RefreshTokenEncoder encoder = new RefreshTokenEncoder(); + return encoder.Decode(RefreshToken); + } + } +} diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs index 5cc206c63..06796c41e 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs @@ -7,7 +7,7 @@ using Tango.Web.Storage; namespace Tango.MachineService.Security { - public class RefreshTokensManager + public class RefreshTokensManager where T : class { private TableStorageManager _manager; @@ -16,16 +16,22 @@ namespace Tango.MachineService.Security _manager = new TableStorageManager(); } - public RefreshTokenEntity GetToken(String refreshToken) + public RefreshTokenEntity GetToken(String refreshToken) { var table = _manager.GetTable(MachineServiceConfig.REFRESH_TOKENS_TABLE_NAME); - return table.GetEntityAsync(MachineServiceConfig.REFRESH_TOKENS_TABLE_PARTITION, refreshToken).Result; + return table.GetEntity>(MachineServiceConfig.REFRESH_TOKENS_TABLE_PARTITION, refreshToken); } - public RefreshTokenEntity InsertOrUpdate(RefreshTokenEntity refreshTokenEntity) + public RefreshTokenEntity InsertOrUpdate(RefreshTokenEntity refreshTokenEntity) { var table = _manager.GetTable(MachineServiceConfig.REFRESH_TOKENS_TABLE_NAME); - return table.InsertOrUpdateEntityAsync(refreshTokenEntity).Result; + return table.InsertOrUpdateEntity(refreshTokenEntity); + } + + public void DeleteToken(RefreshTokenEntity entity) + { + var table = _manager.GetTable(MachineServiceConfig.REFRESH_TOKENS_TABLE_NAME); + table.DeleteEntity(entity); } } } \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj index 22be33277..bf0c15541 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -291,6 +291,7 @@ + @@ -375,7 +376,7 @@ True 51581 / - http://localhost:51581/ + http://localhost:1111/ False False -- cgit v1.3.1