In many projects, because the WEBAPI is open to the outside, at this time, we have to consider the security of interface Exchange data.
Security mechanisms are also more, such as Andriod and WEBAPI exchange data, you can walk the two-way certificate method, but the development cost is relatively large,
Today we are not going to introduce this knowledge, we are talking about a simpler and more common security exchange mechanism
Here to remind readers, all the encryption mechanism is not absolutely safe!
Our goal is that any user or software obtained to our WEBAPI interface URL is not valid for re-accessing the address!
To achieve this goal, we have to add a timestamp to the URL , but it's not enough that the user can modify our timestamp !
So we can MD5 encryption of timestamps, but this is still not enough, the user can directly to our timestamp MD5 oh, because some need to introduce an absolute security
The two parties agreed to the key, and simultaneously add other parameters to confuse!
Note: This key is to be saved in the app with the same copy in our Webapi!
So we agreed to the formula: encryption result =MD5 (timestamp + random number +key+post or get parameters)
Let's start by writing the code in the above formula:
To my environment is ASP. NET MVC, so rewrite an encryption class Apisecurityfilter
1. Get Parameters
if (Request. Headers.contains ("timestamp")) timestamp = Httputility.urldecode (Request. Headers.getvalues ("timestamp"). FirstOrDefault ()); if (Request. Headers.contains ("nonce")) nonce = Httputility.urldecode (Request. Headers.getvalues ("Nonce"). FirstOrDefault ()); if (Request. Headers.contains ("signature")) signature = Httputility.urldecode (Request. Headers.getvalues ("signature"). FirstOrDefault ()); if (string. IsNullOrEmpty (timestamp) | | String. IsNullOrEmpty (nonce) | | String. IsNullOrEmpty (signature)) throw new SecurityException ();
2. Determine if the timestamp exceeds the specified time
Double ts = 0; BOOL Timespanvalidate = Double. TryParse (timestamp, out TS); BOOL Falg = (datetime.utcnow-new DateTime (1970, 1, 1, 0, 0, 0, 0)). Totalmilliseconds-ts >; if (Falg | | (!timespanvalidate)) throw new SecurityException ();
3, post/delete/update three ways to extract parameters
Case ' POST ': Case ' PUT ': Case ' DELETE ': stream stream = HttpContext.Current.Request.InputStream; StreamReader StreamReader = new StreamReader (stream); Sortedparams = new sorteddictionary<string, string> (New Jsonserializer (). Deserialize<dictionary<string, string>> (New JsonTextReader (StreamReader))); Break
4. GET method to extract parameters
Case "GET": idictionary<string, string> parameters = new dictionary<string, string> (); foreach (string key in HttpContext.Current.Request.QueryString) { if (!string. IsNullOrEmpty (key)) { parameters. ADD (Key, Httpcontext.current.request.querystring[key]); } } Sortedparams = new sorteddictionary<string, string> (parameters); Break
5, sorting the above parameters and stitching, forming we want to participate in the MD5 formula of the fourth parameter
StringBuilder query = new StringBuilder (); if (sortedparams! = null) { foreach (var sort in sortedparams.orderby (k = k.key)) { if (!string. IsNullOrEmpty (sort. Key) { query. Append (sort. Key). Append (sort. Value); } } data = query. ToString (). Replace ("", ""); }
6. Start the contract formula to calculate the results and compare the results of the transmission is consistent
var Md5staff = Seedwork.Utils.CharHelper.MD5 (string. Concat (timestamp + nonce + staffid + data), (+); if (!md5staff.equals (signature)) throw new SecurityException ();
The complete code is as follows:
1 public class Apisecurityfilter:actionfilterattribute 2 {3 public override void OnActionExecuting (httpact Ioncontext Actioncontext) 4 {5 var request = Actioncontext.request; 6 7 var method = Req Uest. Method.method; 8 var StaffID = "^***********************************$"; 9 string timestamp = string. Empty, nonce = string. Empty, signature = string. empty;11 if (request. Headers.contains ("timestamp")) timestamp = Request. Headers.getvalues ("timestamp"). FirstOrDefault (), if (request. Headers.contains ("Nonce")) (nonce) = Request. Headers.getvalues ("Nonce"). FirstOrDefault (), if (request. Headers.contains ("signature")) signature = Request. Headers.getvalues ("signature"). FirstOrDefault (); if (string. IsNullOrEmpty (timestamp) | | String. IsNullOrEmpty (nonce) | | String. IsNullOrEmpty (signature)) thRow new SecurityException (); double ts = 0;
NET MVC Webapi utility