First, as an authentication server, you need to provide a appid/appsecret to obtain token such an interface, and then have the following code.
PublicClassAuthcontroller:apicontroller {[HttpGet]Public Httpresponsemessage Token (string AppID ="",String Appsecret ="") {Apiresponseentity rep;var ISV =AppManage.Instance.GetAppISV (AppID, Appsecret);if (ISV! =Null) {string token = TokenManage.Instance.CreateToken (AppID); Rep = new apiresponseentity {Status = interfacestatus.success, BizData = new { Accesstoken = token}}; } else {rep = new apiresponseentity () {Status = interfacestatus.parm_missing, Message = "param error" }; } return Rep. Tohttpresponsemessage (); }}
View Code
The algorithm for creating tokens is self-fulfilling, and I'm doing the MD5 processing of the newly generated GUID, the code is as follows:
String Createtoken (string AppID) { string token =return token;}
View Code
As you can see above, after the token has been generated, a settoken is to store the token in the cache and set the lifetime of a certain period of time, the code is as follows:
void Set (string appid) { var config =string. Format (Rediscachekey.app_token, Token); redisnethelper.set<string>(Key, AppID, DateTime.Now.AddSeconds (config. Tokensurvivaltime)); }
View Code
Why use token to do key, because token changes will cause the ISV token verification invalidation, but with token to do key can be used in the survival cycle, this key can use, to avoid multi-threading to obtain tokens, or other reasons for token invalidation. As an authentication server, you also need to provide an interface such as Refreshtoken, which is used to refresh the token's survival cycle, and the code is similar here.
Second, in the API validation, it is necessary to start the token verification, the code is as follows:
PublicClassOauthhandler:delegatinghandler {ProtectedOverride TaskSendAsync (httprequestmessage request, System.Threading.CancellationToken CancellationToken) {apiresponseentity Repentity =Null;string AppID ="";String IP =Requesthelper.getwebclientip ();if (!Oauthvalidate.ipvalidate (IP)) {repentity =Newapiresponseentity {Status =Interfacestatus.illegalip, Message ="IP Access limit"}; }Else{String token ="";String url =Request. Requesturi.absoluteuri;var routedata =Request. Getroutedata ();String controller = routedata.values["Controller"]. ToString (). ToLower ();String action = routedata.values["Action"]. ToString (). ToLower ();if (Controller. Equals ("Auth") && action. Equals ("Token")) {ReturnBase. SendAsync (Request, CancellationToken); }if (Request. Method = =Httpmethod.get) {var query =Request. Requesturi.parsequerystring (); token = query["Token"]; }if (token = =null | | Token. Length = =0) {repentity =Newapiresponseentity {Status =Interfacestatus.token_faild, Message ="Token invalid"}; }Else{AppID =TokenManage.Instance.Get (token);if (AppID = =null | | AppID. Length = =0) {repentity =Newapiresponseentity {Status =Interfacestatus.token_faild, Message ="Token invalid"}; }Else{if (!Oauthvalidate.apivalidate (String. Format ("{0}/{1}", controller, Action), AppID) {repentity =Newapiresponseentity {Status =interfacestatus.no_access, Message = "API Access limit" };}}} if (repentity ! = null) { var TSC = new taskcompletionsource(); TSC. Setresult (Repentity.tohttpresponsemessage ()); return TSC. Task; } Else { return base. SendAsync (Request, CancellationToken); } } }
View Code
Using a more traditional way, inheriting from Delegatinghandler, and then processing, the first is to do the IP authentication, then the token validity period verification, and then the API authorization call validation. The code for validation is as follows:
PublicStaticBOOL Ipvalidate (StringIP) {var config =ServerConfigManage.Instance.GetServerConfig ();BOOL Ispass =True;if (Ispass &&Config. isstartipwhitelist) {Ispass =Config. Ipwhitelist.contains (IP); }if (Ispass &&Config. isstartipblacklist) {Ispass =!Config. Ipblacklist.contains (IP); }Return Ispass;} public static bool Apivalidate (string API, string AppID) {var config = ServerConfigManage.Instance.GetServerConfig (); ifvar APIs = AppManage.Instance.GetAppApiResource (AppID); return apis! = null && APIs. Contains (API); } return true
View Code
Getserverconfig () is to get the server custom configuration from the Db/cache, and then see whether to turn on the IP whitelist/blacklist, the following code similarly, whether to turn on permission validation.
That authentication server actually ended up here, about the ISV applying for Appid/appsecret. Then the user agrees to the authorization later, the storage AppID and user's correlation relation, needs the spectator to implement independently.
There is also an extension code to mention here, is about the return value of apiresponseentity processing, the code is as follows:
public static httpresponsemessage Tohttpresponsemessage (this responseentity rep, bool Isencrypt = false) {return new Httpresponsemessage (Httpstatuscode.ok) {Content = Span style= "COLOR: #0000ff" >new Stringcontent (isencrypt? Encrypthelper.base64replace (Encrypthelper.aesencryptbase64 (Jsonhelper.tojson (Rep), Config.apiencryptkey)): Jsonhelper.tojson (Rep), System.Text.Encoding.UTF8, " Application/json "
View Code
Self-developed to implement OAuth to do WEBAPI certification