diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-02-24 00:57:14 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-02-24 00:57:14 +0200 |
| commit | 0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b (patch) | |
| tree | bb5e4055020aa4417e1f7703a611353ce44689d6 /Software/Visual_Studio/Tango.Web | |
| parent | 17612c08da93c75d4c941a643bc7602c18f351d8 (diff) | |
| download | Tango-0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b.tar.gz Tango-0adea9eb464a3f2d5d73b2c8c26d32e0d1a3874b.zip | |
Working on refresh tokens...
Diffstat (limited to 'Software/Visual_Studio/Tango.Web')
12 files changed, 202 insertions, 13 deletions
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; } |
