aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2019-02-24 00:57:14 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2019-02-24 00:57:14 +0200
commit0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b (patch)
treebb5e4055020aa4417e1f7703a611353ce44689d6 /Software/Visual_Studio
parent17612c08da93c75d4c941a643bc7602c18f351d8 (diff)
downloadTango-0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b.tar.gz
Tango-0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b.zip
Working on refresh tokens...
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClient.cs2
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginResponse.cs2
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Web/PPCWebClient.cs2
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs2
-rw-r--r--Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs2
-rw-r--r--Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs69
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs24
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs14
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs14
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/TokensManager.cs (renamed from Software/Visual_Studio/Tango.Web/Authentication/TokensManager.cs)2
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/WebToken.cs (renamed from Software/Visual_Studio/Tango.Web/Authentication/WebToken.cs)21
-rw-r--r--Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs (renamed from Software/Visual_Studio/Tango.Web/Authentication/WebTokenResponse.cs)3
-rw-r--r--Software/Visual_Studio/Tango.Web/Storage/BlobStorageManager.cs (renamed from Software/Visual_Studio/Tango.Web/Storage/StorageManager.cs)4
-rw-r--r--Software/Visual_Studio/Tango.Web/Storage/TableStorageManager.cs26
-rw-r--r--Software/Visual_Studio/Tango.Web/Tango.Web.csproj13
-rw-r--r--Software/Visual_Studio/Tango.Web/TangoWebClient.cs23
-rw-r--r--Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs36
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs8
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtTokenFilter.cs19
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokenEncoder.cs26
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs31
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj4
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Web.config4
27 files changed, 327 insertions, 32 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index 48c78e865..3f9133d43 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -326,7 +326,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs
index 78c7bc560..4ae22fa93 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginResponse.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.MachineStudio.Common.Web
{
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClient.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClient.cs
index 7938e1a17..a03f94c78 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClient.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClient.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Tango.Settings;
using Tango.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.MachineStudio.Common.Web
{
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginResponse.cs
index 5d97c6470..73da9ce8f 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginResponse.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginResponse.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.PPC.Common.Web
{
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/PPCWebClient.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/PPCWebClient.cs
index 4897efc90..52c9fdef3 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/PPCWebClient.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/PPCWebClient.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Tango.Settings;
using Tango.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.PPC.Common.Web
{
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 ff698f18f..d696a627c 100644
--- a/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs
+++ b/Software/Visual_Studio/Tango.UnitTesting/Web/JWT_Tokens_TST.cs
@@ -6,7 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.UnitTesting.Web
{
diff --git a/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs b/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs
index 854d1cf96..32cc3f83c 100644
--- a/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs
+++ b/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs
@@ -11,7 +11,7 @@ using System.Web.Http;
using System.Web.Http.Controllers;
using Tango.Logging;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.Web.Controllers
{
diff --git a/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs b/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs
new file mode 100644
index 000000000..43c4804d3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/ExtensionMethods/CloudTableExtensions.cs
@@ -0,0 +1,69 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+
+public static class CloudTableExtensions
+{
+ /// <summary>
+ /// Demonstrate the most efficient storage query - the point query - where both partition key and row key are specified.
+ /// </summary>
+ /// <param name="table">Sample table name</param>
+ /// <param name="partitionKey">Partition key - i.e., last name</param>
+ /// <param name="rowKey">Row key - i.e., first name</param>
+ /// <returns>A Task object</returns>
+ public static async Task<T> GetEntityAsync<T>(this CloudTable table, string partitionKey, string rowKey) where T : class, ITableEntity
+ {
+ TableOperation retrieveOperation = TableOperation.Retrieve<T>(partitionKey, rowKey);
+ TableResult result = await table.ExecuteAsync(retrieveOperation);
+ T customer = result.Result as T;
+ return customer;
+ }
+
+ /// <summary>
+ /// The Table Service supports two main types of insert operations.
+ /// 1. Insert - insert a new entity. If an entity already exists with the same PK + RK an exception will be thrown.
+ /// 2. Replace - replace an existing entity. Replace an existing entity with a new entity.
+ /// 3. Insert or Replace - insert the entity if the entity does not exist, or if the entity exists, replace the existing one.
+ /// 4. Insert or Merge - insert the entity if the entity does not exist or, if the entity exists, merges the provided entity properties with the already existing ones.
+ /// </summary>
+ /// <param name="table">The sample table name</param>
+ /// <param name="entity">The entity to insert or merge</param>
+ /// <returns>A Task object</returns>
+ public static async Task<T> InsertOrUpdateEntityAsync<T>(this CloudTable table, T entity) where T : class, ITableEntity
+ {
+ if (entity == null)
+ {
+ throw new ArgumentNullException("Specified entity is null.");
+ }
+
+ // Create the InsertOrReplace table operation
+ TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(entity);
+
+ // Execute the operation.
+ TableResult result = await table.ExecuteAsync(insertOrMergeOperation);
+ T insertedCustomer = result.Result as T;
+
+ return insertedCustomer;
+ }
+
+ /// <summary>
+ /// Delete an entity
+ /// </summary>
+ /// <param name="table">Sample table name</param>
+ /// <param name="deleteEntity">Entity to delete</param>
+ /// <returns>A Task object</returns>
+ public static async Task DeleteEntityAsync<T>(this CloudTable table, T deleteEntity) where T : class, ITableEntity
+ {
+ if (deleteEntity == null)
+ {
+ throw new ArgumentNullException("Specified entity was null.");
+ }
+
+ TableOperation deleteOperation = TableOperation.Delete(deleteEntity);
+ await table.ExecuteAsync(deleteOperation);
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs b/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs
new file mode 100644
index 000000000..839027ca1
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/Security/RefreshTokenEntity.cs
@@ -0,0 +1,24 @@
+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
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RefreshTokenEntity"/> class.
+ /// </summary>
+ 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
new file mode 100644
index 000000000..213cd3afd
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/Security/RenewTokenRequest.cs
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 000000000..76c381852
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/Security/RenewTokenResponse.cs
@@ -0,0 +1,14 @@
+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/Authentication/TokensManager.cs b/Software/Visual_Studio/Tango.Web/Security/TokensManager.cs
index 5829bfca3..bf5574766 100644
--- a/Software/Visual_Studio/Tango.Web/Authentication/TokensManager.cs
+++ b/Software/Visual_Studio/Tango.Web/Security/TokensManager.cs
@@ -6,7 +6,7 @@ using System.Text;
using System.Threading.Tasks;
using Tango.Transport.Web;
-namespace Tango.Web.Authentication
+namespace Tango.Web.Security
{
public class TokensManager<T> where T : IEquatable<T>
{
diff --git a/Software/Visual_Studio/Tango.Web/Authentication/WebToken.cs b/Software/Visual_Studio/Tango.Web/Security/WebToken.cs
index 14fc49942..006ed9de7 100644
--- a/Software/Visual_Studio/Tango.Web/Authentication/WebToken.cs
+++ b/Software/Visual_Studio/Tango.Web/Security/WebToken.cs
@@ -10,13 +10,14 @@ using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
-namespace Tango.Web.Authentication
+namespace Tango.Web.Security
{
public class WebToken
{
public DateTime Issued { get; protected set; }
public DateTime? Expiration { get; protected set; }
public String AccessToken { get; protected set; }
+ public String RefreshToken { get; protected set; }
public WebToken()
{
@@ -42,6 +43,7 @@ namespace Tango.Web.Authentication
return new WebToken()
{
AccessToken = builder.Build(),
+ RefreshToken = Guid.NewGuid().ToString(),
Expiration = expiration,
Issued = issued,
};
@@ -63,6 +65,14 @@ namespace Tango.Web.Authentication
.Decode(AccessToken);
}
+ public WebToken Renew(String secret, String token)
+ {
+ WebToken webToken = WebToken.FromToken(token);
+ var newToken = CreateNew(secret, DateTime.UtcNow.Add(webToken.Expiration.Value - webToken.Issued));
+ newToken.RefreshToken = webToken.RefreshToken;
+ return newToken;
+ }
+
public static WebToken FromToken(String token)
{
WebToken webToken = new WebToken();
@@ -123,6 +133,7 @@ namespace Tango.Web.Authentication
return new WebToken<T>()
{
AccessToken = builder.Build(),
+ RefreshToken = Guid.NewGuid().ToString(),
Expiration = expiration,
Issued = issued,
Object = obj,
@@ -155,5 +166,13 @@ namespace Tango.Web.Authentication
return webToken;
}
+
+ public new WebToken<T> Renew(String secret, String token)
+ {
+ WebToken<T> webToken = WebToken<T>.FromToken(token);
+ var newToken = WebToken<T>.CreateNew(secret, webToken.Object, DateTime.UtcNow.Add(webToken.Expiration.Value - webToken.Issued));
+ newToken.RefreshToken = webToken.RefreshToken;
+ return newToken;
+ }
}
}
diff --git a/Software/Visual_Studio/Tango.Web/Authentication/WebTokenResponse.cs b/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs
index 190a47cc2..8c8f2f096 100644
--- a/Software/Visual_Studio/Tango.Web/Authentication/WebTokenResponse.cs
+++ b/Software/Visual_Studio/Tango.Web/Security/WebTokenResponse.cs
@@ -5,10 +5,11 @@ using System.Text;
using System.Threading.Tasks;
using Tango.Transport.Web;
-namespace Tango.Web.Authentication
+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/Storage/StorageManager.cs b/Software/Visual_Studio/Tango.Web/Storage/BlobStorageManager.cs
index 17b01d1e2..d3f8b1dc4 100644
--- a/Software/Visual_Studio/Tango.Web/Storage/StorageManager.cs
+++ b/Software/Visual_Studio/Tango.Web/Storage/BlobStorageManager.cs
@@ -8,11 +8,11 @@ using System.Threading.Tasks;
namespace Tango.Web.Storage
{
- public class StorageManager
+ public class BlobStorageManager
{
private CloudBlobClient _client;
- public StorageManager()
+ public BlobStorageManager()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(WebConfig.STORAGE_ACCOUNT);
_client = storageAccount.CreateCloudBlobClient();
diff --git a/Software/Visual_Studio/Tango.Web/Storage/TableStorageManager.cs b/Software/Visual_Studio/Tango.Web/Storage/TableStorageManager.cs
new file mode 100644
index 000000000..7b3a3d513
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Web/Storage/TableStorageManager.cs
@@ -0,0 +1,26 @@
+using Microsoft.WindowsAzure.Storage;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Web.Storage
+{
+ public class TableStorageManager
+ {
+ private CloudTableClient _client;
+
+ public TableStorageManager()
+ {
+ CloudStorageAccount storageAccount = CloudStorageAccount.Parse(WebConfig.STORAGE_ACCOUNT);
+ _client = storageAccount.CreateCloudTableClient();
+ }
+
+ public CloudTable GetTable(String name)
+ {
+ return _client.GetTableReference(name);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
index 961ec04e8..621014496 100644
--- a/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
+++ b/Software/Visual_Studio/Tango.Web/Tango.Web.csproj
@@ -248,16 +248,21 @@
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="ActiveDirectory\ActiveDirectoryManager.cs" />
- <Compile Include="Authentication\WebTokenResponse.cs" />
- <Compile Include="Authentication\TokensManager.cs" />
- <Compile Include="Authentication\WebToken.cs" />
+ <Compile Include="Security\RefreshTokenEntity.cs" />
+ <Compile Include="Security\RenewTokenResponse.cs" />
+ <Compile Include="Security\RenewTokenRequest.cs" />
+ <Compile Include="Security\WebTokenResponse.cs" />
+ <Compile Include="Security\TokensManager.cs" />
+ <Compile Include="Security\WebToken.cs" />
<Compile Include="DeploymentSlot.cs" />
<Compile Include="DeploymentSlotAddressAttribute.cs" />
+ <Compile Include="ExtensionMethods\CloudTableExtensions.cs" />
<Compile Include="ExtensionMethods\DeploymentSlotExtensions.cs" />
<Compile Include="Logging\AzureCloudLogger.cs" />
<Compile Include="SQLServer\SQLServerManager.cs" />
<Compile Include="Storage\ExtensionMethods.cs" />
- <Compile Include="Storage\StorageManager.cs" />
+ <Compile Include="Storage\BlobStorageManager.cs" />
+ <Compile Include="Storage\TableStorageManager.cs" />
<Compile Include="TangoWebApplication.cs" />
<Compile Include="TangoWebClient.cs" />
<Compile Include="WebConfig.cs" />
diff --git a/Software/Visual_Studio/Tango.Web/TangoWebClient.cs b/Software/Visual_Studio/Tango.Web/TangoWebClient.cs
index 42a9d801c..08fc19099 100644
--- a/Software/Visual_Studio/Tango.Web/TangoWebClient.cs
+++ b/Software/Visual_Studio/Tango.Web/TangoWebClient.cs
@@ -5,7 +5,7 @@ using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.Web
{
@@ -70,13 +70,29 @@ namespace Tango.Web
return response;
}
+ private async Task Renew()
+ {
+ var response = await _client.PostJson<RenewTokenRequest, RenewTokenResponse>(GetActionAddress("Renew"), new RenewTokenRequest()
+ {
+ RefreshToken = WebToken.RefreshToken,
+ });
+
+ Token = response.AccessToken;
+ _client.AuthenticationToken = Token;
+
+ WebToken = WebToken.FromToken(Token);
+
+ IsAuthenticated = true;
+ }
+
protected virtual async Task<TResponse> Post<TRequest, TResponse>(String action, TRequest request) where TRequest : class, IWebRequestMessage where TResponse : class, IWebResponseMessage
{
if (IsAuthenticated)
{
if (DateTime.UtcNow >= WebToken.Expiration)
{
- await Login(_lastLoginRequest);
+ await Renew();
+ //await Login(_lastLoginRequest);
}
}
@@ -89,7 +105,8 @@ namespace Tango.Web
{
try
{
- await Login(_lastLoginRequest);
+ //await Login(_lastLoginRequest);
+ await Renew();
var response = await _client.PostJson<TRequest, TResponse>(GetActionAddress(action), request);
return response;
}
diff --git a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
index d645f0e5e..6bbcd1884 100644
--- a/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
+++ b/Software/Visual_Studio/Utilities/Tango.WebClientGenerator/Program.cs
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
using Tango.CodeGeneration;
using Tango.Core.Helpers;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
using Tango.Web.Controllers;
namespace Tango.WebClientGenerator
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
index 467b6ae28..324878f25 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
@@ -18,9 +18,10 @@ using Tango.MachineStudio.Common.Web;
using Tango.Web.Controllers;
using Tango.Web.Helpers;
using Tango.Web.Storage;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
using Tango.Web.ActiveDirectory;
using Tango.MachineService.Filters;
+using Tango.MachineService.Security;
namespace Tango.MachineService.Controllers
{
@@ -34,6 +35,12 @@ namespace Tango.MachineService.Controllers
public String UserGuid { get; set; }
}
+ public class RefreshTokenObject
+ {
+ public String Email { get; set; }
+ public String Password { get; set; }
+ }
+
#region Constructors
/// <summary>
@@ -85,7 +92,7 @@ namespace Tango.MachineService.Controllers
if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion)
{
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER);
var blob = container.GetBlockBlobReference(latestVersion.BlobName);
@@ -121,7 +128,7 @@ namespace Tango.MachineService.Controllers
if (latestVersion != null)
{
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER);
var blob = container.GetBlockBlobReference(latestVersion.BlobName);
@@ -161,7 +168,7 @@ namespace Tango.MachineService.Controllers
{
String newVersionFileName = "Machine Studio Version" + " " + currentVersion.ToString() + ".zip";
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER);
var blob = container.CreateEmptyBlob(newVersionFileName);
@@ -359,6 +366,27 @@ 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/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
index edbab8cbe..0f36fa040 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
@@ -19,7 +19,7 @@ using Tango.Web.Helpers;
using Tango.Web.SMO;
using Tango.Web.Storage;
using System.Data.Entity;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
using Tango.Web.ActiveDirectory;
using Tango.Core.Cryptography;
using Tango.MachineService.Filters;
@@ -86,7 +86,7 @@ namespace Tango.MachineService.Controllers
response.Version = latest_machine_version.Version;
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER);
var blob = container.GetBlockBlobReference(latest_machine_version.BlobName);
@@ -153,7 +153,7 @@ namespace Tango.MachineService.Controllers
response.Version = latest_machine_version.Version;
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER);
var blob = container.GetBlockBlobReference(latest_machine_version.BlobName);
@@ -331,7 +331,7 @@ namespace Tango.MachineService.Controllers
{
String newVersionFileName = $"{machine_version.Name} - Tango Version {currentVersion.ToString()}.tup";
- var manager = new StorageManager();
+ var manager = new BlobStorageManager();
var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER);
var blob = container.CreateEmptyBlob(newVersionFileName);
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtTokenFilter.cs b/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtTokenFilter.cs
index 4cf22cc43..d4b87f1d5 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtTokenFilter.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtTokenFilter.cs
@@ -10,12 +10,24 @@ using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Tango.Transport.Web;
-using Tango.Web.Authentication;
+using Tango.Web.Security;
namespace Tango.MachineService.Filters
{
public class JwtTokenFilter : ActionFilterAttribute
{
+ public bool AllowExpired { get; private set; }
+
+ public JwtTokenFilter()
+ {
+
+ }
+
+ public JwtTokenFilter(bool allowExpired)
+ {
+ AllowExpired = allowExpired;
+ }
+
public override void OnActionExecuting(HttpActionContext actionContext)
{
var authorizationHeader = actionContext.Request.Headers.Authorization;
@@ -28,7 +40,10 @@ namespace Tango.MachineService.Filters
}
catch (JWT.TokenExpiredException)
{
- throw new TokenExpiredException("Token expired.");
+ if (!AllowExpired)
+ {
+ throw new TokenExpiredException("Token expired.");
+ }
}
catch (JWT.SignatureVerificationException)
{
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs
index a6aa71944..0e6d18ddf 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs
@@ -13,5 +13,7 @@ namespace Tango.MachineService
public static String MACHINE_STUDIO_VERSIONS_CONTAINER => ConfigurationManager.AppSettings[nameof(MACHINE_STUDIO_VERSIONS_CONTAINER)].ToString();
public static bool ENFORCE_MACHINE_STUDIO_VERSION => bool.Parse(ConfigurationManager.AppSettings[nameof(ENFORCE_MACHINE_STUDIO_VERSION)].ToString());
public static String JWT_TOKEN_SECRET => ConfigurationManager.AppSettings[nameof(JWT_TOKEN_SECRET)].ToString();
+ public static String REFRESH_TOKENS_TABLE_NAME => ConfigurationManager.AppSettings[nameof(REFRESH_TOKENS_TABLE_NAME)].ToString();
+ public static String REFRESH_TOKENS_TABLE_PARTITION => ConfigurationManager.AppSettings[nameof(REFRESH_TOKENS_TABLE_PARTITION)].ToString();
}
} \ No newline at end of file
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<T>
+ {
+ 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<T>(str);
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs
new file mode 100644
index 000000000..5cc206c63
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Security/RefreshTokensManager.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using Tango.Web.Security;
+using Tango.Web.Storage;
+
+namespace Tango.MachineService.Security
+{
+ public class RefreshTokensManager
+ {
+ private TableStorageManager _manager;
+
+ public RefreshTokensManager()
+ {
+ _manager = new TableStorageManager();
+ }
+
+ public RefreshTokenEntity GetToken(String refreshToken)
+ {
+ var table = _manager.GetTable(MachineServiceConfig.REFRESH_TOKENS_TABLE_NAME);
+ return table.GetEntityAsync<RefreshTokenEntity>(MachineServiceConfig.REFRESH_TOKENS_TABLE_PARTITION, refreshToken).Result;
+ }
+
+ public RefreshTokenEntity InsertOrUpdate(RefreshTokenEntity refreshTokenEntity)
+ {
+ var table = _manager.GetTable(MachineServiceConfig.REFRESH_TOKENS_TABLE_NAME);
+ return table.InsertOrUpdateEntityAsync(refreshTokenEntity).Result;
+ }
+ }
+} \ 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 6dbbe49ab..22be33277 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
@@ -290,6 +290,8 @@
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Security\RefreshTokenEncoder.cs" />
+ <Compile Include="Security\RefreshTokensManager.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
@@ -381,7 +383,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
index fb10e615e..d7413de62 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
@@ -26,7 +26,9 @@
<add key="DEPLOYMENT_SLOT" value="DEV" />
<add key="ENVIRONMENT_GROUP" value="Tango DEV" />
<add key="ENFORCE_MACHINE_STUDIO_VERSION" value="true" />
- <add key="JWT_TOKEN_SECRET" value="GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk" />
+ <add key="JWT_TOKEN_SECRET" value="GQDstcKsx0NHjLOuXOYg5MbeJ1yT0u1iwDVTwine" />
+ <add key="REFRESH_TOKENS_TABLE_NAME" value="RefreshTokens" />
+ <add key="REFRESH_TOKENS_TABLE_PARTITION" value="REFRESH_TOKENS_PART" />
</appSettings>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.