Asp.net-Web-Api

在帶有 Owin 的 Asp.Net Web Api 中同時使用 OAuth 和基本身份驗證

  • February 9, 2015

我已經根據這些部落格文章在我的 Web Api 項目中實現了 OAuth 身份驗證

它執行良好,包括刷新令牌邏輯。

我想為基本身份驗證添加一個選項,以及為預定作業的幾個呼叫添加一個選項。

我已經嘗試添加一個基本身份驗證解決方案作為中間件,但我仍然收到 401 請求不記名令牌。

我可以通過刪除

$$ Authorize $$如果使用者已通過身份驗證,則來自這些 api 呼叫的屬性並在程式碼中手動檢查,但這似乎是解決問題的錯誤方法。 有沒有辦法使用 OWin 同時支持基本身份驗證和 OAuth 身份驗證?

您如何將您的操作或控制器歸因於您想要使用該屬性實現基本身份驗證[OverrideAuthentication]然後您創建自定義身份驗證過濾器屬性,該屬性繼承自Attribute, IAuthenticationFilter以下程式碼

public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
{
   public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
   {
       var req = context.Request;
       // Get credential from the Authorization header 
       //(if present) and authenticate
       if (req.Headers.Authorization != null && "basic".Equals(req.Headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase))
       {
           var rawCreds = req.Headers.Authorization.Parameter;

           var credArray = GetCredentials(rawCreds);

           var clientId = credArray[0];
           var secret = credArray[1];

           if (ValidCredentials(clientId, secret))
           {
               var claims = new List<Claim>()
                     {
                       new Claim(ClaimTypes.Name, clientId)
                     };

               var identity = new ClaimsIdentity(claims, "Basic");
               var principal = new ClaimsPrincipal(new[] { identity });
               // The request message contains valid credential
               context.Principal = principal;
           }
           else
           {
               context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
           }

       }
       else
       {
           context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
       }

       return Task.FromResult(0);
   }

   private string[] GetCredentials(string rawCred)
   {

       var encoding = Encoding.GetEncoding("UTF-8");

       var cred = encoding.GetString(Convert.FromBase64String(rawCred));

       var credArray = cred.Split(':');

       if (credArray.Length == 2)
       {
           return credArray;
       }
       else
       {
           return credArray = ":".Split(':');
       }

   }

   private bool ValidCredentials(string clientId, string secret)
   {

       //compare the values from web.config

       if (clientId == secret)
       {
           return true;
       }
       return false;
   }

   public Task ChallengeAsync(HttpAuthenticationChallengeContext context,CancellationToken cancellationToken)
   {
       context.Result = new ResultWithChallenge(context.Result);
       return Task.FromResult(0);
   }

   public class ResultWithChallenge : IHttpActionResult
   {
       private readonly IHttpActionResult next;
       public ResultWithChallenge(IHttpActionResult next)
       {
           this.next = next;
       }
       public async Task<HttpResponseMessage> ExecuteAsync( CancellationToken cancellationToken)
       {
           var response = await next.ExecuteAsync(cancellationToken);
           if (response.StatusCode == HttpStatusCode.Unauthorized)
           {
               response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic"));
           }
           return response;
       }
   }

   public bool AllowMultiple
   {
       get { return false; }
   }
}

現在,您可以使用它來將控制器或操作歸因於以下程式碼:

[OverrideAuthentication]
   [BasicAuthentication]
   [Route("")]
   public async Task<IHttpActionResult> Get()
{
}

請注意我們如何創建聲明身份並將身份驗證方案設置為基本,您可以在此處放置您想要的任何聲明。

引用自:https://stackoverflow.com/questions/28352998