2013-05-01 137 views
7

我們有一個Web API應用程序,它提供了許多客戶端可以調用和使用的Web方法。它將在IIS中進行託管並進行SSL設置。如何通過ASP.NET Web API使用Active Directory身份驗證?

用戶憑證存儲在Active Directory中,但客戶端不僅在我們的域中,它們可以位於世界任何地方,所以我的理解是我們無法使用Windows集成身份驗證。

如上所述,在我們的場景中驗證用戶的最佳方式是什麼?

我是否應該要求用戶在標題中傳遞用戶名/密碼並提交每個請求?然後,我通過編程方式驗證用戶憑據與Active Directory的對應關係(我們已經有一個組件可以這樣做),例如通過創建一個自定義的ActionFilter在每個動作執行之前運行?

另一種方法可能是創建一個HttpModule,它在每個請求之前運行,並執行身份驗證,如果無效則中止請求。

我的自定義屬性應該是這樣的:

public class ActiveDirectoryAuthAttribute : ActionFilterAttribute 
    { 
     // todo: load from config which can change depending on deployment environment 
     private static readonly bool ShouldRequireHttps = false; 

     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      IPrincipal principal = this.Authentiate(actionContext); 

      if (principal == null) 
      { 
       actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 
      } 
      else 
      { 
       this.SetPrincipal(principal); 
      } 
     } 

     private IPrincipal Authentiate(HttpActionContext actionContext) 
     { 
      if (IsUriSchemaValid(actionContext.Request.RequestUri)) 
      { 
       // is the client certificate known and still valid? 
       // is IP valid? 
       // find user credentials and validate against AD 
       // create the Principle object and return it 
      } 

      return null; 
     } 

     private void SetPrincipal(IPrincipal principal) 
     { 
      Thread.CurrentPrincipal = principal; 

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

     private static bool IsUriSchemaValid(Uri uri) 
     { 
      bool result = true; 

      if (ShouldRequireHttps) 
      { 
       if (!string.Equals(uri.Scheme, "https", StringComparison.InvariantCultureIgnoreCase)) 
       { 
        result = false; 
       } 
      } 

      return result; 
     } 
    } 

然後我的控制器動作裏面我可以訪問的主要目的:

IPrincipal principle = this.User; 

什麼是認證/授權用戶的最佳方式在我們的情況下,如上所述?

在上面,如何從IPrinciple創建一個對象?是否有任何現有的.NET類,或者我不得不創建我的自定義類?

回答

2

我最近一直在和AD做一個公平的比較,我想不出另一種處理這個問題的方法。

使用OAuth類型的方法可能更有意義。提供一種令牌類型路由,該路由最初將接受用戶名和密碼,並將自己創建並加密的令牌返回給被調用者。一旦進行了第一次初始調用,就會將令牌發回給被調用者,然後他們可以在授權頭中爲該調用的每個後續調用使用該令牌。

令牌對於一次呼叫或非常短的時間空間有效。每次你認爲要使用的令牌時,發出另一個令牌。

您也可以考慮使用自定義OAuth實現,而不是使用數據庫進行身份驗證,使用AD身份存儲並使用OAuth承載令牌。由於您使用的是SSL,這實際上非常適合您的情況。

相關問題