2014-05-15 30 views
3

我有一个ASP.Net WebAPI 2.1,我刚刚过渡到使用身份2.0使用持票人令牌。这工作正常。现在我试图拉入一些MVC代码来创建一组登录和用户管理页面。我的问题是,当我将WebApi HttpConfiguration设置为SuppressDefaultHostAuthentication时,我似乎无法从我的剃刀视图中获得Request.IsAuthenticatedRequest.IsAuthenticated使用身份与Owin的MVC和WebAPI

下面是我的代码,我出出主意,我怎么能得到这个对于这两种情况:(

这里是我的Startup.cs其中规定了身份OWIN模块和的WebAPI工作:

public class Startup 
{ 
    public void Configure(IAppBuilder app) 
    { 
     app.CreatePerOwinContext(ApplicationDbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); 

     PublicClientId = "self"; 
     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      TokenEndpointPath = new PathString("/token"), 
      Provider = new ApplicationOAuthProvider(PublicClientId), 
      AuthorizeEndpointPath = new PathString("/api/account/externalLogin"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(14) 
     }; 
     app.UseOAuthBearerTokens(OAuthOptions); 

     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie)) 
      } 
     }); 

     var httpConfiguration = new HttpConfiguration(); 
     // Disable this line to allow Request.IsAuthenticated to work 
     // But by doing this, it allows the 'redirect' to kick in on unauthenticated API requests, which returns a HTML page for a webapi call, rather than the JSON 'unauthenticated' response 
     httpConfiguration.SuppressDefaultHostAuthentication(); 
     httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie)); 
     httpConfiguration.MapHttpAttributeRoutes(); 
     app.UseWebApi(httpConfiguration); 
    } 
} 

这里是我的Global.asax.cs,其中规定了事物的MVC侧(据我所知OWIN不支持任何形式的app.UseMvc()):

public class WebApiApplication : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     // pretty much the defaults here for everything, just renamed 
     AreaRegistration.RegisterAllAreas(); 
     MvcConfig.ConfigureFilters(GlobalFilters.Filters); 
     MvcConfig.ConfigureRoutes(RouteTable.Routes); 
     MvcConfig.ConfigureBundles(BundleTable.Bundles); 
    } 
} 

现在在我的Razor视图中,我想使用Request.IsAuthenticated,如在身份示例中使用的,但在启用httpConfiguration.SuppressDefaultHostAuthentication时失败。我知道这个扩展的目标是在Identity中间件运行后移除当前的身份 - 这样WebAPI身份验证过滤器可以随心所欲地进行操作。但我希望在MVC方面,这种压制不会发生。

例Razor视图:

@if (Request.IsAuthenticated) // false when using httpConfiguration.SuppressDefaultHostAuthentication 
{ 
    <div>User.Identity.Email</div> 
} 

谁能帮助我?这甚至有可能吗?

谢谢!

回答

1

看起来像是关于应用程序构建器的排序。如果我在WebAPI之前放置身份承载配置,那么我的WebAPI请求仍然使用身份OWIN模块。通过在WebAPI配置之后放置Cookie配置,Cookie身份解析发生在WebAPI身份移除后,并在MVC执行之前。

不确定这是否是'正确'的方法去做,但它似乎解决了我打开的所有测试案例。

public class Startup 
{ 
    public void Configure(IAppBuilder app) 
    { 
     app.CreatePerOwinContext(ApplicationDbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); 

     PublicClientId = "self"; 
     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      TokenEndpointPath = new PathString("/token"), 
      Provider = new ApplicationOAuthProvider(PublicClientId), 
      AuthorizeEndpointPath = new PathString("/api/account/externalLogin"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(14) 
     }; 
     app.UseOAuthBearerTokens(OAuthOptions); 

     var httpConfiguration = new HttpConfiguration(); 
     httpConfiguration.SuppressDefaultHostAuthentication(); 
     httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie)); 
     httpConfiguration.MapHttpAttributeRoutes(); 
     app.UseWebApi(httpConfiguration); 

     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie)) 
      } 
     }); 
    } 
} 

编辑 以上的作品,但它似乎是更好地利用app.MapWhen()功能来做到这一点。

public class Startup 
{ 
    public void Configure(IAppBuilder app) 
    { 
     // setup auth for all requests 
     app.CreatePerOwinContext(ApplicationDbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); 

     PublicClientId = "self"; 
     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      TokenEndpointPath = new PathString("/token"), 
      Provider = new ApplicationOAuthProvider(PublicClientId), 
      AuthorizeEndpointPath = new PathString("/api/account/externalLogin"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(14) 
     }; 
     app.UseOAuthBearerTokens(OAuthOptions); 

     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie)) 
      } 
     }); 

     // setup webapi for only /api requests 
     app.MapWhen(
      context => context.Request.Uri.PathAndQuery.StartsWith("/api"), 
      newApp => { 
       var httpConfiguration = new HttpConfiguration(); 
       httpConfiguration.SuppressDefaultHostAuthentication(); 
       httpConfiguration.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie)); 
       httpConfiguration.MapHttpAttributeRoutes(); 
       app.UseWebApi(httpConfiguration); 
      } 
    } 
}  
+0

我很想知道在'MapWhen'动作中重新注册Web API是不是一个好主意。我无法找到如何使用'MapWhen'处理请求的可靠答案。 – CalMlynarczyk

相关问题