【发布时间】:2016-09-15 05:20:22
【问题描述】:
tl;dr:HttpApplication.AuthenticateRequest 事件的 Owin 等效项是什么?
背景
在 IIS 上运行 ASP.net 站点时,全局 System.Web.HttpApplication 对象会在每个请求期间引发 AuthenticateRequest 事件。
各种 http 模块(例如内置的 FormsAuthentication)可以附加到事件。事件处理程序按照它们注册的顺序被调用。设置HttpContext.Current.User 的第一个处理程序是使用的身份验证。
订阅此事件的模块的工作是将HttpContext.Current.User 设置为某个Principal:
IIdentity identity = new GenericIdentity("MBurns", "ContosoAuthentcation");
IPrincipal principal = new GenericPrincipal(identity, null);
HttpContext.Current.User = principal;
一旦分配了HttpContext.Current.User,ASP.net 就知道用户已通过身份验证。 (一旦用户通过身份验证,他们就不再是匿名的)。
任何模块都可以做到
任何人都可以使用web.config 在 ASP.net 中注册自己的IHttpModule:
web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="MySuperCoolAuthenticationModule" type="ContosoAuthModule" />
</modules>
</system.webServer>
该模块很容易编写。您实现了IHttpModule 接口的唯一Init 方法。对我们来说,我们将自己添加为 AuthenticateRequest 事件处理程序:
public class ContosoAuthModule : IHttpModule
{
public void Init(HttpApplication httpApplication)
{
// Register event handlers
httpApplication.AuthenticateRequest += OnApplicationAuthenticateRequest;
}
}
然后您可以执行身份验证用户所需的操作,如果他们是有效用户,请设置HttpContext.Current.User:
private void OnApplicationAuthenticateRequest(object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
String username = SomeStuffToFigureOutWhoIsMakingTheRequest(request);
if (String.IsNullOrWhiteSpace(username))
{
//I don't know who they are :(
return;
}
//I know who they are, they are [username]!
IIdentity identity = new GenericIdentity(username, "ContosoSuperDuperAuthentication");
HttpContext.Current.User = new GenericPrincipal(identity, null);
}
这就是 HttpApplication
MSDN 记录了 HttpApplication 引发的各种事件,以及按什么顺序:
ASP.NET Application Life Cycle Overview for IIS 7.0 (archive.is)
- 验证请求,它检查浏览器发送的信息并确定它是否包含潜在的恶意标记。有关详细信息,请参阅ValidateRequesta 和 Script Exploits Overviewa。
- 如果在 Web.config 文件的 UrlMappingsSectiona 部分中配置了任何 URL,则执行 URL 映射。
- 引发BeginRequest 事件。
- 引发AuthenticateRequesta 事件。
- 引发PostAuthenticateRequest 事件。
- 引发AuthorizeRequest 事件。
- 引发PostAuthorizeRequest 事件。
- 引发ResolveRequestCache 事件。
当它是 ASP.net 和 HttpApplication 时,这一切都很棒。一切都很好理解,很容易解释(在上面的半屏中),并且有效。
但是 HttpApplication 已经过时了。
欧文是新的热点
现在一切都应该是 Owin。 HttpApplication 位于System.Web。人们希望与System.Web 隔离。他们希望这个名为 Owin 的 事物 现在负责。
为了进一步实现这一目标,他们(即任何新的 ASP.net MCV、网络表单或 SignalR 网站)完全禁用了 ASP.net 的身份验证系统:
<system.web>
<authentication mode="None" />
</system.web>
所以没有更多的 HttpApplication.AuthenticateRequest 事件。 :(
什么是 Owin 等价物?
HttpApplication.AuthenticateRequest 的 Owin 等价物是什么?
可以肯定地说,无论从哪里调用我的代码,我的工作仍然是将HttpContext.Current.User 设置为一个身份。
可以肯定地说,无论我的代码在哪里调用表单,我的工作仍然是将HttpContext.Current.User 设置为一个身份吗?
HttpApplication.AuthenticateRequest 的 Owin 等价物是什么?
尝试无效
它没有被调用过:
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using System.Web;
using System.IO;
using Microsoft.Owin.Extensions;
using System.Security.Claims;
using System.Security.Principal;
[assembly: OwinStartup("AnyStringAsLongAsItsNotBlank", typeof(BasicAuthOwin))]
public class BasicAuthOwin
{
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
System.Diagnostics.Trace.WriteLine("They did their best, shoddily-iddly-iddly-diddly");
OnAuthenticateRequest(context);
return next.Invoke();
});
app.UseStageMarker(PipelineStage.Authenticate);
app.Run(context =>
{
return context.Response.WriteAsync("Hello world");
});
}
private void OnAuthenticateRequest(IOwinContext context)
{
var request = context.Request;
String username = SomeStuffToFigureOutWhoIsMakingTheRequest(request);
if (String.IsNullOrWhiteSpace(username))
{
//I don't know who they are :(
return;
}
//I know who they are, they are [username]!
IIdentity identity = new GenericIdentity(username, "ContosoSuperDuperOwinAuthentication");
context.Authentication.User = new ClaimsPrincipal(identity);
}
private string SomeStuffToFigureOutWhoIsMakingTheRequest(IOwinRequest request)
{
//if ((System.Diagnostics.Stopwatch.GetTimestamp % 3) == 0)
// return "";
return "MBurns";
}
}
【问题讨论】:
-
你解决过这个问题吗?我对同样的事情很感兴趣。
-
@deezg 我从来没有这样做过。这没什么大不了的,因为我们都知道 IIS 和 System.Web 不会去任何地方。我刚刚注释掉了 web.config 中的
authentication mode="None"设置(并温柔地拍了拍 Owin “这很好,亲爱的” 拍了拍头) -
:) 感谢您的回复。我现在做的差不多。
-
你最近试过吗?这个应用程序似乎对我有用:pastebin.com/mP4ZSxGQ 在浏览器上显示“Hello world MBurns”(我将 WriteAsync 输出更改为使用 HttpContext.Current.User.Identity.Name)。