2014-05-15 32 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

相關問題