2016-08-15 9 views
0

私はうまくいかないソリューションで同様の投稿を見直しました。Webapi委任ハンドラの返送401応答がOwin Authによってオーバーライドされる

私はIIS 7.xでホストされているMVC 5サイトを持っていて、Webサービスを提供しています。https://www.example.com呼び出し側はapi(Webapi 2.2)エンドポイントにアクセスして特定の機能(https://www.example.com/api/x)を実行することもできます。一部のページ/ apiは保護されていますが、他のページ/保護されていないmvc/web UIセキュリティは、UseCookieAuthenticationおよびUseWsFenerationAuthenticationで構成されたowinミドルウェアによって管理されます。

webuiのセキュリティ保護されたページは、ユーザーが有効なSAMLトークンを持っていない場合、自動的にADFSログイン画面にリダイレクトされます。

セキュリティ保護されたWeb APIでは、Authヘッダーで渡された別のJWTトークンが必要です。

WebapiはMVCと同じアプリケーションプールでホストされています。 WebAPIにはコントローラがありません。代わりに、webapiconfigにはDelegatingHandlerを利用してapi呼び出しをルーティング/通過させるルートがあります。 Delegatingハンドラは、JWTがAuthヘッダに含まれているかどうかを確認し、JWTがJWTを検証する別の内部webapiに進むことができるかどうかを確認するハンドラです。 012Wが存在しない場合、DelegatingHandlerは401を返します。

401のリターンは、要求の継続を短絡し、したがってすべてのowinパイプライン処理をバイパスしていました。しかし、短絡が発生すると、401は返されません。その代わり、要求は継続され、Owin認証に渡され、その後、(302)がADFSログインにリダイレクトされます。なぜ私は考えていない。 応答ステータスコードを401以外に変更すると、Owin Authはそれを無視します。

参照してください以下のコード:

Global.asax.cs

public class Global : HttpApplication 
{ 
    protected void Application_Start(object sender, EventArgs e) 
    { 
     // Code that runs on application startup 
     AreaRegistration.RegisterAllAreas(); 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles);   
    } 
} 

WebApiConfig.cs

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.Routes.MapHttpRoute(
      name: "Apis", 
      routeTemplate: "api/{*path}", 
      handler: HttpClientFactory.CreatePipeline 
      (
       innerHandler: new HttpClientHandler(), 
       handlers: new DelegatingHandler[] { new ApiHandler() } 
      ), 
      defaults: new { path = RouteParameter.Optional }, 
      constraints: null 
     ); 
    } 
} 

ApiHandler.cs

internal class ApiHandler : DelegatingHandler 
{ 
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 

     try 
     { 
      // get jwt from header 
      var jwt = GetJWTFromHeader(request.Headers); 

      if (jwt == null) 
      { 
       response.ReasonPhrase = "Token required"; 
       return await Task.FromResult<HttpResponseMessage>(response); 
      } 
      else if (!IsValidJWT(jwt)) 
      { 
       response.ReasonPhrase = "Invalid token"; 
       return await Task.FromResult<HttpResponseMessage>(response); 
      } 

      response = await base.SendAsync(request, cancellationToken); 

     } 
     catch (Exception ex) 
     { 
      // log error 
      response = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
     } 

     // return result 
     return response; 
    } 
} 

Startup.Auth.cs

public partial class Startup 
{ 
    public void ConfigureAuth(IAppBuilder app) 
    { 
     ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate; 

     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 

     app.UseCookieAuthentication(
      new CookieAuthenticationOptions() 
      { 
       SlidingExpiration = false 
      } 
     ); 

     app.UseWsFederationAuthentication(
      new WsFederationAuthenticationOptions 
      { 
       Wtrealm = ADFS_REALM, 
       MetadataAddress = ADFS_METADATA, 
       UseTokenLifetime = true, 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        SaveSigninToken = true 
       }, 

       Notifications = new WsFederationAuthenticationNotifications 
       { 
        RedirectToIdentityProvider = async r => 
        { 
         // do stuff       
        }, 
        SecurityTokenValidated = async s => 
        { 
         // if we get here, then UI user has valid saml token 
         // do stuff 
        } 
       } 
      } 
     }); 

} 

私は、任意の助けに感謝。詳細が必要な場合はお知らせください。

答えて

0

Finallzのおかげで、私は検索を絞り込み、答えを見つけ出すことができました - 見つけたhere。私の場合、特別な認証設定は必要ありません.PHHandlerのJWTを手動で検査しているからです。しかし、単に私のAPIパスにマップを含むことで、それが自然Owinセキュリティを上書きします:これは答えではありませんが

app.Map("/api", inner => 
{ 
    // nothing to do here since we don't have any concrete controllers to manage special authorization for 
    // we're using apihandlers to pass api traffic through to next stop 
}); 
関連する問題