2017-01-18 19 views
1

すべてのコントローラに対してWindows認証を使用するASP.NET Web API 2アプリケーションがあります。一部のコントローラで基本認証を使用する必要があります。ASP.NET Web API 2アプリケーションのWindows認証と基本認証の有効化

匿名認証とWindows認証の両方を有効にすることはできませんが、一部のコントローラではWindows認証を有効にし、その他の認証では基本認証を有効にすることは可能ですか?

UPDATE:EdSF shared

記事に示すように、ここではフィルタを実装 は、私がこれまで持っているものです。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] 
public class BasicAuthenticationFilter : AuthorizationFilterAttribute 
{ 
    private bool _active = true; 
    private const string ValidUsername = @"Test"; 
    private const string ValidPassword = @"T3st"; 

    public BasicAuthenticationFilter() 
    { 
    } 

    public BasicAuthenticationFilter(bool active) 
    { 
     _active = active; 
    } 

    public override void OnAuthorization(HttpActionContext actionContext) 
    { 
     if (_active) 
     { 
      var identity = ParseAuthorizationHeader(actionContext); 
      if (identity == null) 
      { 
       Challenge(actionContext); 
       return; 
      } 


      if (!OnAuthorizeUser(identity.Name, identity.Password, actionContext)) 
      { 
       Challenge(actionContext); 
       return; 
      } 

      var principal = new GenericPrincipal(identity, null); 

      Thread.CurrentPrincipal = principal; 

      if (HttpContext.Current != null) 
      { 
       HttpContext.Current.User = principal; 
      } 

      base.OnAuthorization(actionContext); 
     } 
    } 

    protected virtual bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext) 
    { 
     if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || 
      !username.Equals(ValidUsername) || !password.Equals(ValidPassword)) 
     { 
      return false; 
     } 

     return true; 
    } 

    protected virtual BasicAuthenticationIdentity ParseAuthorizationHeader(HttpActionContext actionContext) 
    { 
     string authHeader = null; 
     var auth = actionContext.Request.Headers.Authorization; 
     if (auth != null && auth.Scheme == "Basic") 
     { 
      authHeader = auth.Parameter; 
     } 

     if (string.IsNullOrEmpty(authHeader)) return null; 

     authHeader = Encoding.Default.GetString(Convert.FromBase64String(authHeader)); 

     var tokens = authHeader.Split(':'); 
     if (tokens.Length < 2) return null; 

     return new BasicAuthenticationIdentity(tokens[0], tokens[1]); 
    } 

    private void Challenge(HttpActionContext actionContext) 
    { 
     var host = actionContext.Request.RequestUri.DnsSafeHost; 
     actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); 
     actionContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", host)); 
    } 
} 

BasicAuthenticationIdentityクラス:

public class BasicAuthenticationIdentity : GenericIdentity 
{ 
    public BasicAuthenticationIdentity(string name, string password) 
     : base(name, "Basic") 
    { 
     Password = password; 
    } 

    public string Password { get; set; } 
} 

はまた、私の装飾しました基本認証フィルタ付きコントローラ:

[BasicAuthenticationFilter] 
[RoutePrefix("api/BasicAuth")] 
public class BasicAuthController : ApiController 
{ 
    //[BasicAuthenticationFilter] 
    [HttpGet] 
    public IHttpActionResult TestBasicAuth() 
    { 
     return Ok("success"); 
    } 
} 

私はフィドラーから、API /にBasicAuthへの呼び出し、私は戻って401を得たが、それだけで次のような課題を返します

WWW-Authenticate: Negotiate 
WWW-Authenticate: NTLM 

この時点で、フィドラーは再びそれをしようとしますが、代わりに基本を渡すのこの時期に認可スキームでは、交渉をパスします。これも失敗します。

最後にFiddlerが3回目の試行を試みると、実際にはフィルタがリクエストを取得しますが、認証スキームがBasicではなくNegotiateであるため、フィルタはUnauthorizedも返します。

ControllerにBasicAuthenticationFilterを使用させる方法はありますか?事前に

おかげ

+0

impersisationがtrueに設定されている場合、HttpContext.Current.Userが呼び出し元ユーザーのIDを返します。あなたはこの情報を入手し、天気の使用が有効な勝利のユーザーであることを確認することができます。 –

+0

またはこれを行うWinAuthContrlerのようなベースコントロール、そして、このWinAuthContrlerを他のmvcコントロールで継承することができます。 WinAuthControlerはControlerクラスから継承する必要があります。 –

+0

はい、ユーザーがWindowsを使用している場合、そのオブジェクトは設定されますが、ユーザーは基本認証を使用してLinuxボックスから呼び出します。私は、その呼び出しからユーザー名とパスワードを取得できる必要があります。 – Jail

答えて

0

することができます - BASIC AUTH資格情報はHTTP Headers(のみbase64エンコード)に送信されるため。 には、アプリケーションレベルで何かを「有効」にし、APIエンドポイントへのHTTP要求を(手動で)(ヘッダーを検査して)処理するがありません。

基本認証ヘッダー:Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

は、必要に応じても、グローバルControllerまたはActionに適用される、またはすることができAuthorizationFilterを作成this example ...

第Hを参照してください。

+0

この記事でフィルタを実装し、私のコントローラを '[BasicAuthenticationFilter]'で装飾すると、まずWindows Authを経由して401を取得しようとします。したがって、2番目の呼び出しはBasicではなくNegotiateになります。基本認証フィルタに到達すると、AutheticationスキームはNegotiateであるため、戻ります。これまで私が実装してきたことを使って質問を更新する。 – Jail

+0

デバッグ時に@Jailがフィルタヒットするそうでない場合は、すべての要求を処理するグローバル設定がありますか? – EdSF

+0

「AreaRegistration.RegisterAllAreas();」の一環として一度呼び出され、私の更新で説明したように、最初の2つの要求が認証に失敗した後です。私はグローバルハンドラを設定していません。 – Jail