├── .gitattributes
├── .gitignore
├── HMACAuthentication.Client
├── App.config
├── HMACAuthentication.Client.csproj
├── Order.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
├── HMACAuthentication.WebApi
├── App_Start
│ └── WebApiConfig.cs
├── Controllers
│ └── OrdersController.cs
├── Filters
│ └── HMACAuthenticationAttribute.cs
├── Global.asax
├── Global.asax.cs
├── HMACAuthentication.WebApi.csproj
├── Properties
│ └── AssemblyInfo.cs
├── Web.Debug.config
├── Web.Release.config
├── Web.config
└── packages.config
├── README.md
├── WebApiHMACAuthentication.sln
└── packages
├── Microsoft.AspNet.WebApi.5.1.2
└── Microsoft.AspNet.WebApi.5.1.2.nupkg
├── Microsoft.AspNet.WebApi.Client.5.1.2
├── Microsoft.AspNet.WebApi.Client.5.1.2.nupkg
└── lib
│ ├── net45
│ ├── System.Net.Http.Formatting.dll
│ └── System.Net.Http.Formatting.xml
│ └── portable-wp8%2Bnetcore45%2Bnet45
│ ├── System.Net.Http.Formatting.dll
│ └── System.Net.Http.Formatting.xml
├── Microsoft.AspNet.WebApi.Client.5.2.2
├── Microsoft.AspNet.WebApi.Client.5.2.2.nupkg
└── lib
│ ├── net45
│ ├── System.Net.Http.Formatting.dll
│ └── System.Net.Http.Formatting.xml
│ └── portable-wp8+netcore45+net45+wp81+wpa81
│ ├── System.Net.Http.Formatting.dll
│ └── System.Net.Http.Formatting.xml
├── Microsoft.AspNet.WebApi.Core.5.1.2
├── Content
│ └── web.config.transform
├── Microsoft.AspNet.WebApi.Core.5.1.2.nupkg
└── lib
│ └── net45
│ ├── System.Web.Http.dll
│ └── System.Web.Http.xml
├── Microsoft.AspNet.WebApi.WebHost.5.1.2
├── Microsoft.AspNet.WebApi.WebHost.5.1.2.nupkg
└── lib
│ └── net45
│ ├── System.Web.Http.WebHost.dll
│ └── System.Web.Http.WebHost.xml
├── Newtonsoft.Json.5.0.6
├── Newtonsoft.Json.5.0.6.nupkg
└── lib
│ ├── net20
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ ├── net35
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ ├── net40
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ ├── net45
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ ├── netcore45
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ ├── portable-net40%2Bsl4%2Bwp7%2Bwin8
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
│ └── portable-net45%2Bwp80%2Bwin8
│ ├── Newtonsoft.Json.dll
│ └── Newtonsoft.Json.xml
├── Newtonsoft.Json.6.0.4
├── Newtonsoft.Json.6.0.4.nupkg
├── lib
│ ├── net20
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ ├── net35
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ ├── net40
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ ├── net45
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ ├── netcore45
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ ├── portable-net40+sl5+wp80+win8+wpa81
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
│ └── portable-net45+wp80+win8+wpa81
│ │ ├── Newtonsoft.Json.dll
│ │ └── Newtonsoft.Json.xml
└── tools
│ └── install.ps1
└── repositories.config
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
19 | !packages/*/build/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Visual C++ cache files
50 | ipch/
51 | *.aps
52 | *.ncb
53 | *.opensdf
54 | *.sdf
55 | *.cachefile
56 |
57 | # Visual Studio profiler
58 | *.psess
59 | *.vsp
60 | *.vspx
61 |
62 | # Guidance Automation Toolkit
63 | *.gpState
64 |
65 | # ReSharper is a .NET coding add-in
66 | _ReSharper*/
67 | *.[Rr]e[Ss]harper
68 |
69 | # TeamCity is a build add-in
70 | _TeamCity*
71 |
72 | # DotCover is a Code Coverage Tool
73 | *.dotCover
74 |
75 | # NCrunch
76 | *.ncrunch*
77 | .*crunch*.local.xml
78 |
79 | # Installshield output folder
80 | [Ee]xpress/
81 |
82 | # DocProject is a documentation generator add-in
83 | DocProject/buildhelp/
84 | DocProject/Help/*.HxT
85 | DocProject/Help/*.HxC
86 | DocProject/Help/*.hhc
87 | DocProject/Help/*.hhk
88 | DocProject/Help/*.hhp
89 | DocProject/Help/Html2
90 | DocProject/Help/html
91 |
92 | # Click-Once directory
93 | publish/
94 |
95 | # Publish Web Output
96 | *.Publish.xml
97 |
98 | # NuGet Packages Directory
99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100 | #packages/
101 |
102 | # Windows Azure Build Output
103 | csx
104 | *.build.csdef
105 |
106 | # Windows Store app package directory
107 | AppPackages/
108 |
109 | # Others
110 | sql/
111 | *.Cache
112 | ClientBin/
113 | [Ss]tyle[Cc]op.*
114 | ~$*
115 | *~
116 | *.dbmdl
117 | *.[Pp]ublish.xml
118 | *.pfx
119 | *.publishsettings
120 |
121 | # RIA/Silverlight projects
122 | Generated_Code/
123 |
124 | # Backup & report files from converting an old project file to a newer
125 | # Visual Studio version. Backup files are not needed, because we have git ;-)
126 | _UpgradeReport_Files/
127 | Backup*/
128 | UpgradeLog*.XML
129 | UpgradeLog*.htm
130 |
131 | # SQL Server files
132 | App_Data/*.mdf
133 | App_Data/*.ldf
134 |
135 |
136 | #LightSwitch generated files
137 | GeneratedArtifacts/
138 | _Pvt_Extensions/
139 | ModelManifest.xml
140 |
141 | # =========================
142 | # Windows detritus
143 | # =========================
144 |
145 | # Windows image file caches
146 | Thumbs.db
147 | ehthumbs.db
148 |
149 | # Folder config file
150 | Desktop.ini
151 |
152 | # Recycle Bin used on file shares
153 | $RECYCLE.BIN/
154 |
155 | # Mac desktop service store files
156 | .DS_Store
157 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/HMACAuthentication.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B9CECCA4-C107-41DE-BB3D-CBE7E5561059}
8 | Exe
9 | Properties
10 | HMACAuthentication.Client
11 | HMACAuthentication.Client
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | False
37 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
38 |
39 |
40 |
41 |
42 |
43 | False
44 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/Order.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace HMACAuthentication.Client
8 | {
9 | public class Order
10 | {
11 | public int OrderID { get; set; }
12 | public string CustomerName { get; set; }
13 | public string ShipperCity { get; set; }
14 | public Boolean IsShipped { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Net.Http.Headers;
6 | using System.Security.Cryptography;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace HMACAuthentication.Client
12 | {
13 | class Program
14 | {
15 | static void Main(string[] args)
16 | {
17 | RunAsync().Wait();
18 | }
19 |
20 | static async Task RunAsync()
21 | {
22 |
23 | Console.WriteLine("Calling the back-end API");
24 |
25 | string apiBaseAddress = "http://localhost:43326/";
26 |
27 | CustomDelegatingHandler customDelegatingHandler = new CustomDelegatingHandler();
28 |
29 | HttpClient client = HttpClientFactory.Create(customDelegatingHandler);
30 |
31 | var order = new Order { OrderID = 10248, CustomerName = "Taiseer Joudeh", ShipperCity = "Amman", IsShipped = true };
32 |
33 | HttpResponseMessage response = await client.PostAsJsonAsync(apiBaseAddress + "api/orders", order);
34 |
35 | if (response.IsSuccessStatusCode)
36 | {
37 | string responseString = await response.Content.ReadAsStringAsync();
38 | Console.WriteLine(responseString);
39 | Console.WriteLine("HTTP Status: {0}, Reason {1}. Press ENTER to exit", response.StatusCode, response.ReasonPhrase);
40 | }
41 | else
42 | {
43 | Console.WriteLine("Failed to call the API. HTTP Status: {0}, Reason {1}", response.StatusCode, response.ReasonPhrase);
44 | }
45 |
46 | Console.ReadLine();
47 | }
48 |
49 | public class CustomDelegatingHandler : DelegatingHandler
50 | {
51 | //Obtained from the server earlier, APIKey MUST be stored securly and in App.Config
52 | private string APPId = "4d53bce03ec34c0a911182d4c228ee6c";
53 | private string APIKey = "A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc=";
54 |
55 | protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
56 | {
57 |
58 | HttpResponseMessage response = null;
59 | string requestContentBase64String = string.Empty;
60 |
61 | string requestUri = System.Web.HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());
62 |
63 | string requestHttpMethod = request.Method.Method;
64 |
65 | //Calculate UNIX time
66 | DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
67 | TimeSpan timeSpan = DateTime.UtcNow - epochStart;
68 | string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();
69 |
70 | //create random nonce for each request
71 | string nonce = Guid.NewGuid().ToString("N");
72 |
73 | //Checking if the request contains body, usually will be null wiht HTTP GET and DELETE
74 | if (request.Content != null)
75 | {
76 | byte[] content = await request.Content.ReadAsByteArrayAsync();
77 | MD5 md5 = MD5.Create();
78 | //Hashing the request body, any change in request body will result in different hash, we'll incure message integrity
79 | byte[] requestContentHash = md5.ComputeHash(content);
80 | requestContentBase64String = Convert.ToBase64String(requestContentHash);
81 | }
82 |
83 | //Creating the raw signature string
84 | string signatureRawData = String.Format("{0}{1}{2}{3}{4}{5}", APPId, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String);
85 |
86 | var secretKeyByteArray = Convert.FromBase64String(APIKey);
87 |
88 | byte[] signature = Encoding.UTF8.GetBytes(signatureRawData);
89 |
90 | using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray))
91 | {
92 | byte[] signatureBytes = hmac.ComputeHash(signature);
93 | string requestSignatureBase64String = Convert.ToBase64String(signatureBytes);
94 | //Setting the values in the Authorization header using custom scheme (amx)
95 | request.Headers.Authorization = new AuthenticationHeaderValue("amx", string.Format("{0}:{1}:{2}:{3}", APPId, requestSignatureBase64String, nonce, requestTimeStamp));
96 | }
97 |
98 | response = await base.SendAsync(request, cancellationToken);
99 |
100 | return response;
101 | }
102 | }
103 |
104 | private void GenerateAPPKey()
105 | {
106 | using (var cryptoProvider = new RNGCryptoServiceProvider())
107 | {
108 | byte[] secretKeyByteArray = new byte[32]; //256 bit
109 | cryptoProvider.GetBytes(secretKeyByteArray);
110 | var APIKey = Convert.ToBase64String(secretKeyByteArray);
111 | }
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("HMACAuthentication.Client")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("HMACAuthentication.Client")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("651613b5-5996-4172-ad76-c01412e328bb")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/HMACAuthentication.Client/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web.Http;
5 |
6 | namespace HMACAuthentication.WebApi
7 | {
8 | public static class WebApiConfig
9 | {
10 | public static void Register(HttpConfiguration config)
11 | {
12 | config.MapHttpAttributeRoutes();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Controllers/OrdersController.cs:
--------------------------------------------------------------------------------
1 | using HMACAuthentication.WebApi.Filters;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Http;
7 | using System.Security.Claims;
8 | using System.Web.Http;
9 |
10 | namespace HMACAuthentication.WebApi.Controllers
11 | {
12 | [HMACAuthentication]
13 | [RoutePrefix("api/Orders")]
14 | public class OrdersController : ApiController
15 | {
16 | [Route("")]
17 | public IHttpActionResult Get()
18 | {
19 | ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
20 |
21 | var Name = ClaimsPrincipal.Current.Identity.Name;
22 |
23 | return Ok(Order.CreateOrders());
24 | }
25 |
26 | [Route("")]
27 | public IHttpActionResult Post(Order order)
28 | {
29 | return Ok(order);
30 | }
31 |
32 | }
33 |
34 | #region Helpers
35 |
36 | public class Order
37 | {
38 | public int OrderID { get; set; }
39 | public string CustomerName { get; set; }
40 | public string ShipperCity { get; set; }
41 | public Boolean IsShipped { get; set; }
42 |
43 |
44 | public static List CreateOrders()
45 | {
46 | List OrderList = new List
47 | {
48 | new Order {OrderID = 10248, CustomerName = "Taiseer Joudeh", ShipperCity = "Amman", IsShipped = true },
49 | new Order {OrderID = 10249, CustomerName = "Ahmad Hasan", ShipperCity = "Dubai", IsShipped = false},
50 | new Order {OrderID = 10250,CustomerName = "Tamer Yaser", ShipperCity = "Jeddah", IsShipped = false },
51 | new Order {OrderID = 10251,CustomerName = "Lina Majed", ShipperCity = "Abu Dhabi", IsShipped = false},
52 | new Order {OrderID = 10252,CustomerName = "Yasmeen Rami", ShipperCity = "Kuwait", IsShipped = true}
53 | };
54 |
55 | return OrderList;
56 | }
57 | }
58 |
59 | #endregion
60 | }
61 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Filters/HMACAuthenticationAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Http;
6 | using System.Net.Http.Headers;
7 | using System.Security.Cryptography;
8 | using System.Security.Principal;
9 | using System.Text;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 | using System.Web;
13 | using System.Web.Http;
14 | using System.Web.Http.Filters;
15 | using System.Web.Http.Results;
16 |
17 | namespace HMACAuthentication.WebApi.Filters
18 | {
19 | public class HMACAuthenticationAttribute : Attribute, IAuthenticationFilter
20 | {
21 | private static Dictionary allowedApps = new Dictionary();
22 | private readonly UInt64 requestMaxAgeInSeconds = 300; //5 mins
23 | private readonly string authenticationScheme = "amx";
24 |
25 | public HMACAuthenticationAttribute()
26 | {
27 | if (allowedApps.Count == 0)
28 | {
29 | allowedApps.Add("4d53bce03ec34c0a911182d4c228ee6c", "A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc=");
30 | }
31 | }
32 |
33 | public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
34 | {
35 | var req = context.Request;
36 |
37 | if (req.Headers.Authorization != null && authenticationScheme.Equals(req.Headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase))
38 | {
39 | var rawAuthzHeader = req.Headers.Authorization.Parameter;
40 |
41 | var autherizationHeaderArray = GetAutherizationHeaderValues(rawAuthzHeader);
42 |
43 | if (autherizationHeaderArray != null)
44 | {
45 | var APPId = autherizationHeaderArray[0];
46 | var incomingBase64Signature = autherizationHeaderArray[1];
47 | var nonce = autherizationHeaderArray[2];
48 | var requestTimeStamp = autherizationHeaderArray[3];
49 |
50 | var isValid = isValidRequest(req, APPId, incomingBase64Signature, nonce, requestTimeStamp);
51 |
52 | if (isValid.Result)
53 | {
54 | var currentPrincipal = new GenericPrincipal(new GenericIdentity(APPId), null);
55 | context.Principal = currentPrincipal;
56 | }
57 | else
58 | {
59 | context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
60 | }
61 | }
62 | else
63 | {
64 | context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
65 | }
66 | }
67 | else
68 | {
69 | context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
70 | }
71 |
72 | return Task.FromResult(0);
73 | }
74 |
75 | public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
76 | {
77 | context.Result = new ResultWithChallenge(context.Result);
78 | return Task.FromResult(0);
79 | }
80 |
81 | public bool AllowMultiple
82 | {
83 | get { return false; }
84 | }
85 |
86 | private string[] GetAutherizationHeaderValues(string rawAuthzHeader)
87 | {
88 |
89 | var credArray = rawAuthzHeader.Split(':');
90 |
91 | if (credArray.Length == 4)
92 | {
93 | return credArray;
94 | }
95 | else
96 | {
97 | return null;
98 | }
99 |
100 | }
101 |
102 | private async Task isValidRequest(HttpRequestMessage req, string APPId, string incomingBase64Signature, string nonce, string requestTimeStamp)
103 | {
104 | string requestContentBase64String = "";
105 | string requestUri = HttpUtility.UrlEncode(req.RequestUri.AbsoluteUri.ToLower());
106 | string requestHttpMethod = req.Method.Method;
107 |
108 | if (!allowedApps.ContainsKey(APPId))
109 | {
110 | return false;
111 | }
112 |
113 | var sharedKey = allowedApps[APPId];
114 |
115 | if (isReplayRequest(nonce, requestTimeStamp))
116 | {
117 | return false;
118 | }
119 |
120 | byte[] hash = await ComputeHash(req.Content);
121 |
122 | if (hash != null)
123 | {
124 | requestContentBase64String = Convert.ToBase64String(hash);
125 | }
126 |
127 | string data = String.Format("{0}{1}{2}{3}{4}{5}", APPId, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String);
128 |
129 | var secretKeyBytes = Convert.FromBase64String(sharedKey);
130 |
131 | byte[] signature = Encoding.UTF8.GetBytes(data);
132 |
133 | using (HMACSHA256 hmac = new HMACSHA256(secretKeyBytes))
134 | {
135 | byte[] signatureBytes = hmac.ComputeHash(signature);
136 |
137 | return (incomingBase64Signature.Equals(Convert.ToBase64String(signatureBytes), StringComparison.Ordinal));
138 | }
139 |
140 | }
141 |
142 | private bool isReplayRequest(string nonce, string requestTimeStamp)
143 | {
144 | if (System.Runtime.Caching.MemoryCache.Default.Contains(nonce))
145 | {
146 | return true;
147 | }
148 |
149 | DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
150 | TimeSpan currentTs = DateTime.UtcNow - epochStart;
151 |
152 | var serverTotalSeconds = Convert.ToUInt64(currentTs.TotalSeconds);
153 | var requestTotalSeconds = Convert.ToUInt64(requestTimeStamp);
154 |
155 | if ((serverTotalSeconds - requestTotalSeconds) > requestMaxAgeInSeconds)
156 | {
157 | return true;
158 | }
159 |
160 | System.Runtime.Caching.MemoryCache.Default.Add(nonce, requestTimeStamp, DateTimeOffset.UtcNow.AddSeconds(requestMaxAgeInSeconds));
161 |
162 | return false;
163 | }
164 |
165 | private static async Task ComputeHash(HttpContent httpContent)
166 | {
167 | using (MD5 md5 = MD5.Create())
168 | {
169 | byte[] hash = null;
170 | var content = await httpContent.ReadAsByteArrayAsync();
171 | if (content.Length != 0)
172 | {
173 | hash = md5.ComputeHash(content);
174 | }
175 | return hash;
176 | }
177 | }
178 | }
179 |
180 | public class ResultWithChallenge : IHttpActionResult
181 | {
182 | private readonly string authenticationScheme = "amx";
183 | private readonly IHttpActionResult next;
184 |
185 | public ResultWithChallenge(IHttpActionResult next)
186 | {
187 | this.next = next;
188 | }
189 |
190 | public async Task ExecuteAsync(CancellationToken cancellationToken)
191 | {
192 | var response = await next.ExecuteAsync(cancellationToken);
193 |
194 | if (response.StatusCode == HttpStatusCode.Unauthorized)
195 | {
196 | response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(authenticationScheme));
197 | }
198 |
199 | return response;
200 | }
201 | }
202 | }
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="HMACAuthentication.WebApi.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Global.asax.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Http;
6 | using System.Web.Routing;
7 |
8 | namespace HMACAuthentication.WebApi
9 | {
10 | public class WebApiApplication : System.Web.HttpApplication
11 | {
12 | protected void Application_Start()
13 | {
14 | GlobalConfiguration.Configure(WebApiConfig.Register);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/HMACAuthentication.WebApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | HMACAuthentication.WebApi
15 | HMACAuthentication.WebApi
16 | v4.5
17 | true
18 |
19 |
20 |
21 |
22 |
23 |
24 | true
25 | full
26 | false
27 | bin\
28 | DEBUG;TRACE
29 | prompt
30 | 4
31 |
32 |
33 | pdbonly
34 | true
35 | bin\
36 | TRACE
37 | prompt
38 | 4
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll
64 |
65 |
66 | ..\packages\Microsoft.AspNet.WebApi.Client.5.1.2\lib\net45\System.Net.Http.Formatting.dll
67 |
68 |
69 | ..\packages\Microsoft.AspNet.WebApi.Core.5.1.2\lib\net45\System.Web.Http.dll
70 |
71 |
72 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.1.2\lib\net45\System.Web.Http.WebHost.dll
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | Global.asax
85 |
86 |
87 |
88 |
89 |
90 |
91 | Web.config
92 |
93 |
94 | Web.config
95 |
96 |
97 |
98 |
99 | 10.0
100 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | True
110 | True
111 | 43326
112 | /
113 | http://localhost:43326/
114 | False
115 | False
116 |
117 |
118 | False
119 |
120 |
121 |
122 |
123 |
130 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("HMACAuthentication.WebApi")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("HMACAuthentication.WebApi")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("36630be0-9e53-4d1b-8b92-da6d60118b89")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/HMACAuthentication.WebApi/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ASP.NET Web API HMAC Authentication (API Key Authentication)
2 | ========================
3 |
4 | Project shows how to secure ASP.NET Web API using API Keys, this technique is useful when TLS protocol is not an option and transmitting data should be done securely.
5 |
--------------------------------------------------------------------------------
/WebApiHMACAuthentication.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30501.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMACAuthentication.Client", "HMACAuthentication.Client\HMACAuthentication.Client.csproj", "{B9CECCA4-C107-41DE-BB3D-CBE7E5561059}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMACAuthentication.WebApi", "HMACAuthentication.WebApi\HMACAuthentication.WebApi.csproj", "{C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {B9CECCA4-C107-41DE-BB3D-CBE7E5561059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {B9CECCA4-C107-41DE-BB3D-CBE7E5561059}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {B9CECCA4-C107-41DE-BB3D-CBE7E5561059}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {B9CECCA4-C107-41DE-BB3D-CBE7E5561059}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {C34ED7DB-C840-42AA-889F-D2F64DD2D0A8}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.5.1.2/Microsoft.AspNet.WebApi.5.1.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.5.1.2/Microsoft.AspNet.WebApi.5.1.2.nupkg
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.1.2/Microsoft.AspNet.WebApi.Client.5.1.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.1.2/Microsoft.AspNet.WebApi.Client.5.1.2.nupkg
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.1.2/lib/net45/System.Net.Http.Formatting.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.1.2/lib/net45/System.Net.Http.Formatting.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.1.2/lib/portable-wp8%2Bnetcore45%2Bnet45/System.Net.Http.Formatting.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.1.2/lib/portable-wp8%2Bnetcore45%2Bnet45/System.Net.Http.Formatting.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.2.2/Microsoft.AspNet.WebApi.Client.5.2.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.2.2/Microsoft.AspNet.WebApi.Client.5.2.2.nupkg
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.2.2/lib/net45/System.Net.Http.Formatting.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.2.2/lib/net45/System.Net.Http.Formatting.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Client.5.2.2/lib/portable-wp8+netcore45+net45+wp81+wpa81/System.Net.Http.Formatting.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Client.5.2.2/lib/portable-wp8+netcore45+net45+wp81+wpa81/System.Net.Http.Formatting.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Core.5.1.2/Content/web.config.transform:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Core.5.1.2/Microsoft.AspNet.WebApi.Core.5.1.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Core.5.1.2/Microsoft.AspNet.WebApi.Core.5.1.2.nupkg
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.Core.5.1.2/lib/net45/System.Web.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.Core.5.1.2/lib/net45/System.Web.Http.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.WebHost.5.1.2/Microsoft.AspNet.WebApi.WebHost.5.1.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.WebHost.5.1.2/Microsoft.AspNet.WebApi.WebHost.5.1.2.nupkg
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.WebHost.5.1.2/lib/net45/System.Web.Http.WebHost.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Microsoft.AspNet.WebApi.WebHost.5.1.2/lib/net45/System.Web.Http.WebHost.dll
--------------------------------------------------------------------------------
/packages/Microsoft.AspNet.WebApi.WebHost.5.1.2/lib/net45/System.Web.Http.WebHost.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | System.Web.Http.WebHost
5 |
6 |
7 |
8 | Provides a global for ASP.NET applications.
9 |
10 |
11 |
12 |
13 |
14 | Gets the global .
15 |
16 |
17 | Extension methods for
18 |
19 |
20 | Maps the specified route template.
21 | A reference to the mapped route.
22 | A collection of routes for the application.
23 | The name of the route to map.
24 | The route template for the route.
25 |
26 |
27 | Maps the specified route template and sets default route.
28 | A reference to the mapped route.
29 | A collection of routes for the application.
30 | The name of the route to map.
31 | The route template for the route.
32 | An object that contains default route values.
33 |
34 |
35 | Maps the specified route template and sets default route values and constraints.
36 | A reference to the mapped route.
37 | A collection of routes for the application.
38 | The name of the route to map.
39 | The route template for the route.
40 | An object that contains default route values.
41 | A set of expressions that specify values for routeTemplate.
42 |
43 |
44 | Maps the specified route template and sets default route values, constraints, and end-point message handler.
45 | A reference to the mapped route.
46 | A collection of routes for the application.
47 | The name of the route to map.
48 | The route template for the route.
49 | An object that contains default route values.
50 | A set of expressions that specify values for routeTemplate.
51 | The handler to which the request will be dispatched.
52 |
53 |
54 | A that passes ASP.NET requests into the pipeline and write the result back.
55 |
56 |
57 | Initializes a new instance of the class.
58 | The route data.
59 |
60 |
61 | Initializes a new instance of the class.
62 | The route data.
63 | The message handler to dispatch requests to.
64 |
65 |
66 | Provides code that handles an asynchronous task
67 | The asynchronous task.
68 | The HTTP context.
69 |
70 |
71 | A that returns instances of that can pass requests to a given instance.
72 |
73 |
74 | Initializes a new instance of the class.
75 |
76 |
77 | Provides the object that processes the request.
78 | An object that processes the request.
79 | An object that encapsulates information about the request.
80 |
81 |
82 | Gets the singleton instance.
83 |
84 |
85 | Provides the object that processes the request.
86 | An object that processes the request.
87 | An object that encapsulates information about the request.
88 |
89 |
90 | Provides a registration point for the simple membership pre-application start code.
91 |
92 |
93 | Registers the simple membership pre-application start code.
94 |
95 |
96 | Represents the web host buffer policy selector.
97 |
98 |
99 | Initializes a new instance of the class.
100 |
101 |
102 | Gets a value that indicates whether the host should buffer the entity body of the HTTP request.
103 | true if buffering should be used; otherwise a streamed request should be used.
104 | The host context.
105 |
106 |
107 | Uses a buffered output stream for the web host.
108 | A buffered output stream.
109 | The response.
110 |
111 |
112 | Provides the catch blocks used within this assembly.
113 |
114 |
115 | Gets the label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteBufferedResponseContentAsync.
116 | The label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteBufferedResponseContentAsync.
117 |
118 |
119 | Gets the label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteErrorResponseContentAsync.
120 | The label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteErrorResponseContentAsync.
121 |
122 |
123 | Gets the label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.ComputeContentLength.
124 | The label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.ComputeContentLength.
125 |
126 |
127 | Gets the label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteStreamedResponseContentAsync.
128 | The label for the catch block in System.Web.Http.WebHost.HttpControllerHandler.WriteStreamedResponseContentAsync.
129 |
130 |
131 | Gets the label for the catch block in System.Web.Http.WebHost.WebHostExceptionCatchBlocks.HttpWebRoute.GetRouteData.
132 | The catch block in System.Web.Http.WebHost.WebHostExceptionCatchBlocks.HttpWebRoute.GetRouteData.
133 |
134 |
135 |
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/Newtonsoft.Json.5.0.6.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/Newtonsoft.Json.5.0.6.nupkg
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/net20/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/net20/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/net35/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/net35/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/net40/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/net40/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/net45/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/net45/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/netcore45/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/netcore45/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/portable-net40%2Bsl4%2Bwp7%2Bwin8/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/portable-net40%2Bsl4%2Bwp7%2Bwin8/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.5.0.6/lib/portable-net45%2Bwp80%2Bwin8/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.5.0.6/lib/portable-net45%2Bwp80%2Bwin8/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/Newtonsoft.Json.6.0.4.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/Newtonsoft.Json.6.0.4.nupkg
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/net20/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/net20/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/net35/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/net35/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/net40/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/net40/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/net45/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/net45/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/netcore45/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/netcore45/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/lib/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tjoudeh/WebApiHMACAuthentication/adb24234389f55962b1a68f53b091add2029e4a7/packages/Newtonsoft.Json.6.0.4/lib/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/packages/Newtonsoft.Json.6.0.4/tools/install.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | # open json.net splash page on package install
4 | # don't open if json.net is installed as a dependency
5 |
6 | try
7 | {
8 | $url = "http://james.newtonking.com/json"
9 | $dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
10 |
11 | if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
12 | {
13 | # user is installing from VS NuGet console
14 | # get reference to the window, the console host and the input history
15 | # show webpage if "install-package newtonsoft.json" was last input
16 |
17 | $consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
18 |
19 | $props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
20 | [System.Reflection.BindingFlags]::NonPublic)
21 |
22 | $prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
23 | if ($prop -eq $null) { return }
24 |
25 | $hostInfo = $prop.GetValue($consoleWindow)
26 | if ($hostInfo -eq $null) { return }
27 |
28 | $history = $hostInfo.WpfConsole.InputHistory.History
29 |
30 | $lastCommand = $history | select -last 1
31 |
32 | if ($lastCommand)
33 | {
34 | $lastCommand = $lastCommand.Trim().ToLower()
35 | if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json"))
36 | {
37 | $dte2.ItemOperations.Navigate($url) | Out-Null
38 | }
39 | }
40 | }
41 | else
42 | {
43 | # user is installing from VS NuGet dialog
44 | # get reference to the window, then smart output console provider
45 | # show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation
46 |
47 | $instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
48 | [System.Reflection.BindingFlags]::NonPublic)
49 | $consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
50 | [System.Reflection.BindingFlags]::NonPublic)
51 | if ($instanceField -eq $null -or $consoleField -eq $null) { return }
52 |
53 | $instance = $instanceField.GetValue($null)
54 | if ($instance -eq $null) { return }
55 |
56 | $consoleProvider = $consoleField.GetValue($instance)
57 | if ($consoleProvider -eq $null) { return }
58 |
59 | $console = $consoleProvider.CreateOutputConsole($false)
60 |
61 | $messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
62 | [System.Reflection.BindingFlags]::NonPublic)
63 | if ($messagesField -eq $null) { return }
64 |
65 | $messages = $messagesField.GetValue($console)
66 | if ($messages -eq $null) { return }
67 |
68 | $operations = $messages -split "=============================="
69 |
70 | $lastOperation = $operations | select -last 1
71 |
72 | if ($lastOperation)
73 | {
74 | $lastOperation = $lastOperation.ToLower()
75 |
76 | $lines = $lastOperation -split "`r`n"
77 |
78 | $installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1
79 |
80 | if ($installMatch)
81 | {
82 | $dte2.ItemOperations.Navigate($url) | Out-Null
83 | }
84 | }
85 | }
86 | }
87 | catch
88 | {
89 | # stop potential errors from bubbling up
90 | # worst case the splash page won't open
91 | }
92 |
93 | # yolo
--------------------------------------------------------------------------------
/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------