3

ベアラー トークンを使用して Identity 2.0 を使用するように移行したばかりの ASP.Net WebAPI 2.1 があります。これはうまくいきます。今、いくつかの MVC コードを取り込んで、一連のログイン ページとユーザー管理ページを作成しようとしています。私の問題は、WebApiをRequest.IsAuthenticatedに設定すると、Razor ビューから作業できないように見えることです。HttpConfigurationSuppressDefaultHostAuthentication

以下は私のコードです。これを両方のシナリオで機能させる方法については、アイデアがありません:(

Startup.csIdentity OWIN モジュールと WebAPI をセットアップするmyは次のとおりです。

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 側をセットアップします (AFAIK 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 ビューで、Identity サンプルで使用されているように を使用したいのですが、が有効になっているとRequest.IsAuthenticated失敗します。httpConfiguration.SuppressDefaultHostAuthenticationこの拡張機能の目的は、Identity ミドルウェアの実行後に現在の ID を削除することであることを理解しています。これにより、WebAPI 認証フィルターが好きなように処理できるようになります。しかし、MVC 側では、抑制が発生しないことを願っています。

Razor ビューの例:

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

誰でも私を助けることができますか?これは可能ですか?

ありがとう!

4

1 に答える 1

2

アプリビルダーの注文がすべてのようです。ID ベアラー構成を WebAPI の前に配置すると、WebAPI 要求は引き続き ID OWIN モジュールを使用します。Cookie 構成を WebAPI 構成の後に配置することで、WebAPI ID の削除後、MVC の実行前に Cookie ID の解決が行われます。

これが「正しい」方法であるかどうかはわかりませんが、私が開いているすべてのテストケースを解決しているようです。

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);
            }
    }
}    
于 2014-05-15T15:10:26.230 に答える