public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType); ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(user.UserName); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); }
AuthenticationManager 在 Microsoft.Owin.Security命名空间下,而这个接口是定义在Microsoft.OWin.dll中.
OWin ,它是由微软ASP.NET小组成员组织成立的一个开源项目。目标是解耦服务器和应用,这里面的服务器主要是指web 服务器,比如说IIS等,全称是Open Web Interface for .Net。OWin可以说是一套定义,默认它是没有什么具体的实现的
在如今web飞快发展的年代,这种模式已经不能够满足灵活多变的需求。越是轻量级,组件化的东西,越能够快速适应变化,更何况.NET现在要吸引开源社区的注意,只有把这一块打通了,越来越多的强大的开源组件才能够出现在.NET的世界里,比如说写一个开源的ASP.NET web服务器。
我们上面说Owin是一套定义,它通过将服务器与应用程序之间的交互归纳为一个方法签名,称之为“应用程序代理(application delegate)”
AppFunc = Func<IDictionary<string, object>, Task>;
在一个基于Owin的应用程序中的每一个组件都可以通过这样的一个代理来与服务器进行交互。 这们这里的交互其实是与服务器一起来处理http request,比如说ASP.NET管理模型中的那些事件,认证,授权,缓存等等,原先我们是通过自定义的http module,在里面拿到包含了request和response的HttpContext对象,进行处理。而现在我们能拿到的就是一个Dictionary。
可是别小看了这个Dictionary,我们所有的信息比如Application state, request state,server state等等这些信息全部存在这个数据结构中。这个dictionary会在Owin处理request的管道中进行传递,没错有了OWin之后,我们就不再是与ASP.NET 管道打交道了,而是OWin的管道,但是这个管道相对于ASP.NET 管道而言更灵活,更开放。
这个字典在OWin管道的各个组件中传输时,你可以任意的往里面添加或更改数据。 OWin默认为我们定义了以下的数据:
MVC 5默认的start up配置类
VS除了为我们引用OWin相关dll,以及移除FormsAuthenticationModule以外,还为我们在App_Start文件夹里添加了一个Startup.Auth.cs的文件。
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// 配置Middleware 組件
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
CookieSecure = CookieSecureOption.Never,
});
}
}
UseCookieAuthentication是一IAppBuilder 的一个扩展方法,定义在Microsoft.Owin.Security.Cookies.dll中。
CookieAuthenticationExtensions.cs
public static IAppBuilder UseCookieAuthentication(this IAppBuilder app,
CookieAuthenticationOptions options)
{
if (app == null)
{
throw new ArgumentNullException("app");
}
app.Use(typeof(CookieAuthenticationMiddleware), app, options);
app.UseStageMarker(PipelineStage.Authenticate);
return app;
}
有了这些数据以后,我们就不需要和.NET的那些对象打交道了,比如说ASP.NET MVC中的HttpContextBase, 以及WEB API 中的 HttpRequestMessage和HttpResponseMessage。我们也不需要再考虑system.web 这个dll里的东西,我们只需要通过OWin就可以拿到我们想要的信息,做我们想做的事了。而OWin,它本身和web服务器或者IIS没有任何关系。