Add Owin Middleware for the IIS Host ASP Web API

Source: Internet
Author: User

To deploy the Owin app on IIS

To deploy the OWIN app on IIS, add only the Package:Microsoft.OWIN.Host.SystemWeb package. It provides APIs for all Owin configurations, middleware registrations, and so on. What we need to do is in fact the same as Selfhost.

    • We still need to implement the startup class, but it is not started by WebApp. We need to define this as the startup class of Owin by hitting [Assembly:owinstartup (startup)] on the Startup class, which automatically discovers and calls the configuration method when the application is running.
    • In the configuration method of the startup class we can configure our middleware.

Systemweb actually implemented a owinhttpmodule to register according to Middleware's requirements IIS for various events, and then executes the associated middleware.

Let's take a look at the pipeline model for IIS Integrated mode HttpRequest processing.

Which part of our middleware runs in the IIS pipeline is by calling Appbuilder. Usestagemarker (pipelinestage.authenticate); This extension method is defined. Where Pipelinestate is like the following optional values:

 Public enumpipelinestage{Authenticate=0, Postauthenticate=1, Authorize=2, Postauthorize=3, Resolvecache=4, Postresolvecache=5, Maphandler=6, Postmaphandler=7, Acquirestate=8, Postacquirestate=9, Prehandlerexecute=Ten,}

The above enumeration values correspond to the corresponding links in the IIS pipeline. The stage designation has the following rules:

1. The default stage is Prehandlerexecute

2. Each Usestagemaker call specifies that the middleware of the registration between the call and the previous call is run in the stage specified in the Usestagemaker

3. The order in which the stage should be specified should be consistent with the processing order of the IIS pipeline

4. If the stage has a specified order that is inconsistent with the IIS pipeline processing order, the previous stage specified in the IIS pipeline later overrides the stage specified earlier in the IIS pipeline.

It sounds a bit around the mouth. In fact, understanding the cause and implementation is easy to understand. The reason for this rule is that the IIS pipeline is in a fixed order, and the execution of middleware in Owin is in the order of registration, and when Owin is deployed in IIS, middleware execution is dependent on the IIS pipeline event. Therefore, there is no conflict unless the specified stage order is consistent with the IIS pipeline order.

Add authenticate OWIN to the Web API middleware

We first create a generic Web API project, add the following interface, and then deploy it on IIS.

[Routeprefix ("api/persons")]     Public classPersoncontroller:apicontroller {[Route ("{ID}")] [authorize]//GET API/VALUES/5         Public stringGet (intID) {return "Jensen"; }    }

At this point, if the access to the interface will be 401 unauthorized errors.

The next step is to add Authmiddleware as the Webapi validation module.

First add Authenticatemiddleware

 Public classAuthenticatemiddleware {Privatefunc<idictionary<string,Object, task>Nextappfunc;  PublicAuthenticatemiddleware (func<idictionary<string,Object, task>Nextmiddlewarefunc) {Nextappfunc=Nextmiddlewarefunc; }         Public AsyncTask Invoke (idictionary<string,Object>parameters) {Trace.WriteLine ("Auth Middleware");            Trace.WriteLine (HttpContext.Current.CurrentNotification); varIdentity =NewGenericIdentity ("Jensen"); parameters["server. User"] =NewGenericPrincipal (Identity,New string[] {"Admin" }); if(Nextappfunc! =NULL)            {                awaitnextappfunc.invoke (parameters); }        }    }

Then add the startup class to register Authenticatemiddleware, and specify run stage as authenticate.

[Assembly:owinstartup (typeof(Owiniishost.startup))] namespace owiniishost{    publicclass  Startup    {        publicvoid  Configuration (iappbuilder appBuilder)        {            appbuilder.use<AuthenticateMiddleware> ();            Appbuilder.usestagemarker (pipelinestage.authenticate);     }}}

This allows us to get the desired result when we revisit the API defined earlier. Because in Authenticatemiddleware we pass all the requests validated.

Here's a bit of a question at first, Webapi is based on HttpContext.User to get the user information for the current request. However, instead of assigning a value directly to HttpContext.User in Authenticatemiddleware, we assign the user information to the Owin environment parameter of key Server.user. There is a suspended in the middle. I answered my question by looking at the source code of the Systemweb package.

First, the Owin environment parameter type that we received in our middleware is aspnetdictionary, and we can see its implementation:

Internalaspnetdictionary (Ipropertysource propertysource)//constructor, where Propertysource is passed in from outside {_propertysource =Propertysource; }Objectidictionary<string,Object. This[stringkey]//The Index property, we set the user information to Server.user key when the method is called {Get            {                Objectvalue; returnPropertiestrygetvalue (Key, outValue)?Value:extra[key]; }            Set            {                if(!Propertiestrysetvalue (key, value)) {Strongextra[key]=value; }            }        }Private BOOLPropertiestrysetvalue (stringKeyObjectvalue) {            Switch(key. Length) {//..... ignore some code here                 Case  One:                    if(string. Equals (Key,"server. User", StringComparison.Ordinal)) {Serveruser=(IPrincipal) value;//assignment to Serveruser propertyreturn true; }                    Break; //... ignore some code here            }            return false; }InternalIPrincipal Serveruser {Get            {                return_propertysource.getserveruser (); }            Set{_propertysource.setserveruser (value);//Propertysource Setserveruser method is finally adjusted} }

Now the key is to see how _propertysource is achieved. Discover _propetysource as an instance of the Owincallcontext type by looking at the code that created aspnetdictionary. Look at its implementation of Setserveruser:

void AspNetDictionary.IPropertySource.SetServerUser (IPrincipal value)        {            = value; // The truth is, when we give the server. When the User key is assigned, value is actually assigned to the HttpContext directly.             Thread.CurrentPrincipal = value;        }

Reference:

Aspnetkatana source, including Systemwebpackage

Add Owin Middleware for the IIS Host ASP Web API

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.