Objective:
- Building a backend management system for ASP. Mvc5+ef6+easyui 1.4.3+unity4.x injection-MVC WEBAPI user authentication (1)
Recalling the previous section, we took advantage of Webapi simple login and the same domain access and cross-domain access to get tokens, you can jump to the previous section to download the code to do it together.
Continuing on to the previous article, we will then demonstrate the use of the received token to access the interface, management interface, using the System Rights Management interface, each interface authorization (management interface for the reading part, because you need to read the beginning of the Rights Management Section (section 18-27) to read this section)
Development environment:
vs2015+ No database (analog data)
Sample code download access password 8CA3
Knowledge Points:
- WEBAPI Permission Validation
- Applied to the actual
- Debugging
Start: 1. Filter validation
We've also used filters to verify the action permissions on the action, the interface is no exception, in the action, in each visit with token information, perhaps you can use the following in the HTTP request header to attach token
Add Filter Class: Supportfilter and Inherit authorizeattribute permission filter Onauthorization base class method
Using system.linq;using system.web;using system.web.http;using system.web.security;namespace Apps.WebApi.Core{ public class Supportfilter:authorizeattribute {//override the base class validation method, add our custom ticket to verify public override void Onaut Horization (System.Web.Http.Controllers.HttpActionContext actioncontext) {//url get token var co ntent = actioncontext.request.properties["Ms_httpcontext"] as httpcontextbase; var token = content. request.querystring["Token"]; if (!string. IsNullOrEmpty (token)) {//Decrypt user ticket and verify that the user name password matches if (Validateticket (token)) {base. IsAuthorized (Actioncontext); } else {handleunauthorizedrequest (actioncontext); }}//If authentication information is not available and anonymous access is not allowed, return unverified 401 else {var attributes = a CtionContext.ActionDescriptor.GetCustomAttributes<allowanonymousattribute> (). Oftype<allowanonymousattribute> (); BOOL isanonymous = attributes. Any (a = A is allowanonymousattribute); if (isanonymous) base. Onauthorization (Actioncontext); else Handleunauthorizedrequest (Actioncontext); }}//verify user name password (match session, or database data match) private bool Validateticket (string encrypttoken) { Decrypt ticket var strticket = Formsauthentication.decrypt (Encrypttoken). UserData; Get username and password from ticket var index = strticket.indexof ("&"); String userName = strticket.substring (0, index); string password = strticket.substring (index + 1); Get session, not by stating the user exits, or the session has expired var token = Httpcontext.current.session[username]; if (token = = null) {return false; }//Compare the tokens in the session with the if (token. ToString () = = EncrypttokeN) {return true; } return false; } }}
Httpactioncontext is not able to take the parameters of the URL, you need to convert to HttpContextBase, this class I have comments, it is easy to read.
1. Take the token from the URL and use the previously encrypted method to uncover the token and derive the username from the token
2. Use username to get token in session
3.ValidateTicket validation to determine if the token in the session is the same as obtained?
2. Apply to the actual
Finally, each action is annotated, and when the interface is invoked, it is preferable to determine if there is permission to access
3. Run the Debug
Before debugging, we need to write some code to access
Modify Home Index Code
<script src= "~/scripts/jquery-1.10.2.min.js" ></script><style>html,body{height:100%}.box{ Filter:progid:DXImageTransform.Microsoft.gradient (startcolorstr= ' #6699FF ', endcolorstr= ' #6699FF '); Background-image:linear-gradient (Bottom, #69F 0, #69F 100%) background-image:-o-linear-gradient (bottom, #69F 0, #69F 100%); Background-image:-moz-linear-gradient (bottom, #69F 0, #69F 100%); Background-image:-webkit-linear-gradient ( Bottom, #69F 0, #69F 100%) background-image:-ms-linear-gradient (bottom, #69F 0, #69F 100%); margin:0 auto;position: relative;width:100%;height:100%}.login-box{width:100%;max-width:500px;height:400px;position:absolute;top:50%; margin-top:-200px}@ @media screen and (min-width:500px) {. login-box{left:50%;margin-left:-250px}}.form{width:100%; max-width:500px;height:275px;margin:25px Auto 0 auto;padding-top:25px}.login-content{height:300px;width:100%; max-width:500px; padding:0px; COLOR:RGB (128, 0, 128); line-height:1.5!important; " >255,250,2550,.6); Float:left}.input-group{margin:0 0 30px 0!important}.form-control,.input-group{height:40px}.form-group{margin-bottom:0!important}.login-title{ padding:20px 10px; padding:0px; COLOR:RGB (128, 0, 128); line-height:1.5!important; " >0,0,0,.6)}.login-title h1{margin-top:10px!important}.login-title small{color: #fff}.link p{line-height:20px; margin-top:30px}.btn-sm{padding:8px 24px!important;font-size:16px!important}</style><div class= "box" Style= "margin:100px;height:400px;width:500px;" > <div class= "Login-box" > <div class= "login-title text-center" > Add a button and div to show the results:
We are getting the right data. If there is no token, our results will return a 401
You can download the code to set the breakpoint in
You can debug the order of token processing for the program!
Summarize:This section explains how to use token to access an interface that requires authorization! Using the MVC filter, the permission check is prioritized when the action is invoked, thus completing the sample interface authorization for the user.
The above section is generally sufficient, if you (ˇ?ˇ) want to ~ more in-depth and fine granularity authorization, then each interface must be individually authorized
If you are interested, you can continue to read the following administrative authorization for the API
--------------------------------------------------------------------------------------------------------Ugly Split-line----------- ------------------------------------------------------------------------------
The following shows how to manage the interface, which requires you to read the 18-27 section of the series before reading! Because the big department takes advantage of the previous management interface functions and code, is closely linked, but it does not matter, even if you do not study the previous series of articles, may also be able to get knowledge from this section!
Knowledge Points:1. Take the API interface in all class libraries
2. Management interface
3. Authorizing the interface
4. Add permission validation to the filter
Begin:Look back at our module management:
Manages the action (opcode) in each controller
The same is true of our Webapi, where each controller's opcode is populated with data in Sysmodule and Sysmoduleoperation tables at WEBAPI runtime
1. Get all API interfaces in the class libraryThis really works, gets the interface that you can normally use to manage or automatically test the interface
The controller as a URL, the Aciton as a opcode inserted into the data table as a permission set, similar to the previous permission system //Get the API Manager collection<apidescription> Apicoll = GlobalConfiguration.Configuration.Services.GetApiExplorer (). apidescriptions; Ilookup
The first foreach obtains the controller, and the second foreach gets the action under the controller. Let's add this to the index in the home and follow up and see the properties of the model in group and M, respectively.
Now you know how to add a watch!
foreach (var group in apigroups) {string controllername = group. Key.controllername; ----------Insert Controller Rootmodel = M_BLL. GetById (controllername); if (Rootmodel = = null) {Sysmodulemodel model = new Sysmodulemodel () {Id = controllername, Name = Controllername, 中文版 Name = "", ParentID = "Apiinterfaceauth", Url = "api/" + controllername, iconic = "Fa fa-television", Enable = true, Remark = "Api Interface Authorization ", Sort = 1, Createperson =" Admin ", Createtime = DateTime.Now, islast = true}; M_bll. Create (ref errors, model); } //-----------Insert Action foreach (var m in group) {String actionname = M.ac Tiondescriptor.actionname; Sysmoduleoperatemodel model = Operatebll.getbyid (m.actiondescriptor.actionname); if (model = = NULL) {model = new Sysmoduleoperatemodel (); Model. Id = Controllername + actionname; Model. Name = M.documentation = = null? Actionname:m.documentation; Model. KeyCode = ActionName; Model. ModuleID = Controllername; Model. IsValid = true; Model. Sort = 0; Operatebll.create (ref errors, model); } } }
After running the database will be automatically added, a few data
2. Management interfaceTable data with our common is no difference, in the interface to do a switch to do as a switch, I did a pull down to switch the type
Change the query condition when switching the drop-down
<div style= "Float:left" > menu Type Toggle: <select class= "Easyui-combobox" name= "Swicthtype" id= "Swicthtype" Style= "width:80px;height:26px;margin-right:10px; "> <option value=" Menu "> System menu </option> <option value=" API ">api interface </option> </select> </div>
$ (' #swicthType '). ComboBox ({ editable:false, onselect:function (record) { if (Record.value = = "API") { $ (' #List '). Treegrid ({"url": ' @Url. Action ("GetList")? Id=apiinterfaceauth '}); $ (' #OptList '). DataGrid (' LoadData ', {total:0, rows: []}); else { $ (' #List '). Treegrid ({"url": ' @Url. Action ("GetList")? Id=0 '}); $ (' #OptList '). DataGrid (' LoadData ', {total:0, rows: []});}} );
3. Authorizing the interfaceAfter authorization can be queried to:
For a better distinction, I'll just give the Super admin get interface permission
4. Add validation to the filterAt this point we need to copy the verification code of the filter in the system before use, and slightly modified to the following code:
public class Supportfilter:authorizeattribute {//override the base class validation method, add our custom ticket to verify public override void Onaut Horization (System.Web.Http.Controllers.HttpActionContext actioncontext) {//url get token var co Ntent = Actioncontext.request.properties[configpara.ms_httpcontext] as httpcontextbase; var token = content. Request.querystring[configpara.token]; if (!string. IsNullOrEmpty (token)) {//decrypts user ticket and verifies that the user name password matches//Controller,action,id in the context of the read request var routes = new RouteCollection (); Routeconfig.registerroutes (routes); Routedata Routedata = routes. Getroutedata (content); The controller of the extraction area Action,id string controller = ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName; string action = ActionContext.ActionDescriptor.ActionName; URL path string filePath = Httpcontext.curRent. Request.filepath; if (Loginusermanage.validateticket (token) && validdatepermission (token, controller, action, FilePath)) {//Is logged in, has permissions, and there is no single sign-on limit base. IsAuthorized (Actioncontext); } else {handleunauthorizedrequest (actioncontext); }}//If authentication information is not available and anonymous access is not allowed, return unverified 401 else {var attributes = a Ctioncontext.actiondescriptor.getcustomattributes<allowanonymousattribute> (). Oftype<allowanonymousattribute> (); BOOL isanonymous = attributes. Any (a = A is allowanonymousattribute); if (isanonymous) base. Onauthorization (Actioncontext); else Handleunauthorizedrequest (Actioncontext); }} public bool Validdatepermission (string token, string controller, string action, String filePath) {BOOL Bresult = false; List<permmodel> perm = null; Perm = (list<permmodel>) Httpcontext.current.session[filepath]; if (perm = = null) {SYSUSERBLL USERBLL = new Sysuserbll () {m_ Rep = new Sysuserrepository (new Dbcontainer ()), Sysrightrep = new Sysrightrepository (new Dbcontainer ()) }; {var userName = Loginusermanage.decrypttoken (token. Trim ()); Perm = userbll.getpermission (userName, Controller);//Get the current user's permission list Httpcontext.current.session[filepath] = perm;//Gets the Quanjiang into the session called by the Controller}//queries whether the current action has permission to operate, greater than 0 indicates there is, otherwise no int count = Perm. Where (A = a.keycode.tolower () = = action. ToLower ()). Count (); if (Count > 0) {bresult = true; } else { Bresult = false; Loginusermanage.redirecturl (); }} return bresult; } }
In this way, the access time will be the current access to the Controller and action to check the permissions, no permission to return 401
Next, write two ways to test a Get method that accesses values, a post that accesses values
<script> $ (function () {$ ("#Login"). Click (function () {$.ajax ({type: "Get", URL: "/api/account/login", data: {userName: $ ("#username"). Val (), Password: $ ("#password"). V Al ()}, Success:function (data, status) {if (data.type==0) { Alert ("Login Failed"); Return } alert ("Login Successful: Token" + data.message); $ ("#myToken"). HTML (data.message); }, Error:function (e) {alert ("Login failed!"); }, Complete:function () {}}); }); $ ("#getData"). Click (function () {$.ajax ({type: "Get", url: "/api/values/get/5?t Oken= "+ $ (" #myToken "). html (), Success:function (data, status) {alert (data); }, Error:function (e) {alert ("Failed!"); }, Complete:function () {}}); }); $ ("#postData"). Click (function () {$.ajax ({type: "post", url: "/api/values/post?"). Token= "+ $ (" #myToken "). html (), Data:{value:" 123 "}, Success:function (data, status) { alert (data); }, Error:function (e) {alert (e); }, Complete:function () {}}); }); });</script>
Summarize:In fact, based on the WEBAPI permissions they are also designed so that you can integrate into your existing permission system to
Thank you for taking the time to read this section, so-called praise high urine far, hey ...
MVC WEBAPI user authentication (2)