将OWIN App部署在IIS上                                           

要想将Owin App部署在IIS上,只添加Package:Microsoft.OWIN.Host.SystemWeb包即可。它提供了所有Owin配置,Middleware注册等方面的Api.我们需要做的其实和SelfHost差不多。

  • 我们依然需要实现Startup类,但是不是通过WebApp来启动了。我们需要通过将Startup类打上[assembly: OwinStartup(typeof(Startup))]来定义这是OWIN的Startup类,当应用运行的时候会自动发现并调用Configuration方法
  • 在Startup类的Configuration方法中我们可以配置我们的Middleware。

SystemWeb其实是实现了一个OwinHttpModule来根据MiddleWare的需求注册IIS的各种事件,然后执行相关的Middleware.

先看一下IIS集成模式的HttpRequest处理的管道模型。

我们的Middleware运行在IIS管道中哪个环节是通过调用appBuilder.UseStageMarker(PipelineStage.Authenticate);这个扩展方法来定义的。其中PipelineState有如下可选值:

public enum PipelineStage
{
Authenticate = ,
PostAuthenticate = ,
Authorize = ,
PostAuthorize = ,
ResolveCache = ,
PostResolveCache = ,
MapHandler = ,
PostMapHandler = ,
AcquireState = ,
PostAcquireState = ,
PreHandlerExecute = ,
}

以上枚举值对应IIS管道中的对应环节。Stage的指定有如下规则:

1. 默认的Stage为PreHandlerExecute

2. 每次UseStageMaker的调用指定了该次调用与前一次调用之间的注册的Middleware均在该次UseStageMaker中指定的Stage中运行

3. Stage的指定顺序应该与IIS管道的处理顺序一致

4. 如果Stage的指定顺序与IIS管道处理顺序不一致,在后面指定的在IIS管道中靠前的Stage会覆盖在其前面指定的在IIS管道中靠后的Stage.

听上去有点绕口。其实理解了原因和实现就容易理解了。这种规则的原因是:IIS管道是有固定顺序的,而OWIN中Middleware的执行也是按照注册的先后顺序的,而当OWIN部署在IIS中时Middleware的执行又是依赖与IIS管道事件的,所以只有当指定的Stage顺序与IIS管道顺序一致时才不会有冲突。

为Web Api添加Authenticate OWIN Middleware                                 

我们首先创建一个普通的web api工程,添加如下接口,然后部署在IIS上。

[RoutePrefix("api/persons")]
public class PersonController : ApiController
{
[Route("{id}")]
[Authorize]
// GET api/values/5
public string Get(int id)
{
return "Jensen";
}
}

这时候如果去访问该接口会得到401未授权的错误。

接下来通过添加AuthMiddleware来作为WebApi验证模块。

首先添加AuthenticateMiddleware

public class AuthenticateMiddleware
{
private Func<IDictionary<string, object>, Task> nextAppFunc;
public AuthenticateMiddleware(Func<IDictionary<string, object>, Task> nextMiddleWareFunc)
{
nextAppFunc = nextMiddleWareFunc;
} public async Task Invoke(IDictionary<string, object> parameters)
{
Trace.WriteLine("Auth Middleware");
Trace.WriteLine(HttpContext.Current.CurrentNotification); var identity = new GenericIdentity("jensen");
parameters["server.User"] = new GenericPrincipal(identity, new string[] { "admin" });
if (nextAppFunc != null)
{
await nextAppFunc.Invoke(parameters);
}
}
}

然后添加Startup类来注册AuthenticateMiddleware,并指定运行Stage为Authenticate.

[assembly: OwinStartup(typeof(OwinIISHost.Startup))]
namespace OwinIISHost
{
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
appBuilder.Use<AuthenticateMiddleware>();
appBuilder.UseStageMarker(PipelineStage.Authenticate); }
}
}

这样当我们再次访问前面定义的api时,就能得到期望的结果了。因为在AuthenticateMiddleware中我们对所有请求都通过了验证。

这里一开始有点疑问,WebApi中是根据HttpContext.User来获取当前请求的用户信息的。但是我们在AuthenticateMiddleware中并没有直接给HttpContext.User赋值,而是将User信息赋值到key 为server.user的OWIN环境参数中。这中间有个断档。通过查看SystemWeb Package的源码,解答了我的疑问。

首先,我们的Middleware中接收到的OWIN环境参数类型为AspNetDictionary,可以查看其实现:

internal AspNetDictionary(IPropertySource propertySource)//构造函数,这里propertySource由外部传入
{
_propertySource = propertySource;
} object IDictionary<string, object>.this[string key]//索引属性,我们设置User信息给server.user key时该方法会被调用
{
get
{
object value;
return PropertiesTryGetValue(key, out value) ? value : Extra[key];
}
set
{
if (!PropertiesTrySetValue(key, value))
{
StrongExtra[key] = value;
}
}
} private bool PropertiesTrySetValue(string key, object value)
{
switch (key.Length)
{
//....ignore some code here
case :
if (string.Equals(key, "server.User", StringComparison.Ordinal))
{
ServerUser = (IPrincipal)value;//赋值给ServerUser属性
return true;
}
break;
//...ignore some code here
}
return false;
} internal IPrincipal ServerUser
{
get
{
return _propertySource.GetServerUser();
}
set
{
_propertySource.SetServerUser(value);//最后还是调了propertySource的SetServerUser方法
}
}

那现在关键就看_propertySource是如何实现的了。通过查看创建AspNetDictionary的代码发现_propetySource为OwinCallContext类型的实例。看看它对SetServerUser的实现:

void AspNetDictionary.IPropertySource.SetServerUser(IPrincipal value)
{
_httpContext.User = value;//真相大白,其实当我们给server.User key赋值时,value其实直接就赋给了HttpContext。
Thread.CurrentPrincipal = value;
}

参考:

AspNetKatana源码,包含SystemWebPackage

为IIS Host ASP.NET Web Api添加Owin Middleware的更多相关文章

  1. 为Asp.Net Web Api添加Http基本认证

    Asp.net Web Api提供了RESTFul web服务的编程接口.默认RESTFul 服务没有提供任何验证或者基于角色的验证,这显然不适合Put.Post.Delete这些操作.Aps.net ...

  2. ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API

    在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...

  3. asp.net web api添加统一异常处理

    1.自定义异常处理过滤器 /// <summary> /// 自定义异常处理过滤器 /// </summary> public class CustomExceptionFil ...

  4. ASP.NET Web API与Owin OAuth:调用与用户相关的Web API

    在前一篇博文中,我们通过以 OAuth 的 Client Credential Grant 授权方式(只验证调用客户端,不验证登录用户)拿到的 Access Token ,成功调用了与用户无关的 We ...

  5. 自定义DelegatingHandler为ASP.NET Web Api添加压缩与解压的功能

    HTTP协议中的压缩 Http协议中使用Accept-Encoding和Content-Encoding头来表示期望Response内容的编码和当前Request的内容编码.而Http内容的压缩其实是 ...

  6. Asp.net Web Api添加异常筛选器

    一.定义一个异常筛选器 using System;using System.Collections.Generic;using System.Linq;using System.Web;using S ...

  7. ASP.NET Web API与Owin OAuth:调用与用户相关的Web API(非第三方登录)

    授权完成添加属性 ClaimsIdentity oAuthIdentity = await CreateAsync(user/*userManager*/, OAuthDefaults.Authent ...

  8. [转] JSON Web Token in ASP.NET Web API 2 using Owin

    本文转自:http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/ ...

  9. JSON Web Token in ASP.NET Web API 2 using Owin

    In the previous post Decouple OWIN Authorization Server from Resource Server we saw how we can separ ...

随机推荐

  1. UML学习-1 UML 简介

    UML 是什么 Unified Modeling Language(UML)又称统一建模语言或标准建模语言,是始于 1997 年一个 OMG 标准,它是一个支持模型化和软件系统开发的图形化语言,为软件 ...

  2. mapreduce&GFS&bigtable learning

    之前在学习udf的时候接触到了mapreduce,感觉很酷,于是学习了一下,看了mapreduce和GFS的论文,但是没有总结,只是看了一遍 准备利用在学校的时间,学习一下bigtable,然后再认真 ...

  3. git branch 常用语句详解

    删除远程分支 git push origin --delete <branchName> 查看本地分支 git branch 创建本地新分支 git branch <branchNa ...

  4. R语言和中国地图

    上图是R语言绘制的按地域分布的数据图.更科学,更严谨,也更有质感的样子. 今天瞎写点东西,我在想数据分析的意义是什么,也许就是研究事物存在的形式.而事物存在的形式是什么样子呢,从最初的三维空间,爱因斯 ...

  5. spring3: AOP 之切面实例化模型 ——跟我学spring3

    所谓切面实例化模型指何时实例化切面. Spring AOP支持AspectJ的singleton.perthis.pertarget实例化模型(目前不支持percflow.percflowbelow ...

  6. WPF的外观装饰类——Border

    public class Border : System.Windows.Controls.Decorator 说明:在另一个元素的周围绘制边框.背景或同时绘制二者.

  7. IIS注册.NET

    IIS中ASP.NET的版本号此时可选的有1.1.2.0和4.0三个,如果想让IIS把3个版本都集成上,那NET Framework 3种都要安装,默认安装到的是C 盘. IIS注册方式如下:1.1: ...

  8. mysql数据库(一):建表与新增数据

    一. 学习目标 理解什么是数据库,什么是表 怎样创建数据库和表(create) 怎样往表里插入数据(insert) 怎样修改表里的数据(update) 怎样删除数据库,表以及数据(delete) 二. ...

  9. SVN与Git优缺点比较

    1.SVN优缺点优点: 1. 管理方便,逻辑明确,符合一般人思维习惯. 2. 易于管理,集中式服务器更能保证安全性. 3. 代码一致性非常高. 4. 适合开发人数不多的项目开发. 缺点: 1. 服务器 ...

  10. samba配置只读和可以写入的共享

    编辑smb.conf 1.在[global]中 找到 security = 将其改为 security = share 2. 在文件中加入自定义的共享目录 [attachment] path=/dat ...