Asp.net-Web-Api
在身份驗證過濾器中的 ChallengeAsync 方法的上下文中設置結果
這個問題與我在這裡提供的答案有關。OP的評論讓我思考了一下。我建議在身份驗證過濾器
IHttpActionResult的方法中使用這樣的類實現。ChallengeAsyncpublic 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", "realm=localhost")); } return response; } }取而代之的是,我可以
ChallengeAsync像這樣簡化。public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) { var result = await context.Result.ExecuteAsync(cancellationToken); if (result.StatusCode == HttpStatusCode.Unauthorized) { result.Headers.WwwAuthenticate.Add( new AuthenticationHeaderValue("Basic", "realm=localhost")); } context.Result = new ResponseMessageResult(result); }這使我免於創建一個實現類
IHttpActionResult,但這是正確的方法嗎?我有一種不安的感覺,從性能的角度來看這有點糟糕,因為感覺就像我正在將操作結果轉換為 HttpResponseMessage 並返回到操作結果。與使用上面的程式碼相比,任何關於此處需要一個單獨的類的指針IHttpActionResult都將像我建議的那樣實現。
目的是使用第一種方法而不是第二種方法。例如,請參閱基本身份驗證範例(也可用於 MVC),它遵循第一種方法: http ://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/BasicAuthentication/ReadMe.txt
第二種方法大多有效。我不會太在意性能的觀點;無論哪種方式,您都在分配一個操作結果對象和一個響應消息對象,所以我看不出有太大的區別。
但是,我推薦第一種方法有幾個原因:
- 第二種方法在 MVC 中的工作方式不同。MVC 和 Web API 都有身份驗證過濾器,它們的工作方式基本相同。但是在 MVC 中,沒有等效於 ResponseMessageResult(HttpContext 會根據需要進行更新,而不是返回一個 HttpResponseMessage 可以被每個呼叫者在堆棧中替換)。如果您的身份驗證過濾器有一個 MVC 實現,那麼您最終可能會在那裡執行第一種方法。
- 它稍微改變了預期的管道行為。ChallengeAsync 中的程式碼比它返回的 context.Result 中的程式碼執行得更早。例如,如果程式碼更改了 HttpRequestMessage 上的屬性並且影響了稍後過濾器的 ChallengeAsync 邏輯,則行為可能與預期不同。
該框架絕對可以更容易地實現介面;隨意對此工作項目進行投票: https ://aspnetwebstack.codeplex.com/workitem/1456