2017-10-15 200 views
0

我正在使用HttpClient爲基於ABP的Web服務創建WPF客戶端。當用戶未登錄時HttpClient.GetAsync上的System.IO.IOException

當我向未登錄的用戶或沒有權限的用戶發出AbpAuthorizeAttribute註釋的控制器方法的請求時,我得到了一個System.IO.IOException

在瀏覽器中,我得到了這個JSON:

{ 
    "result": null, 
    "targetUrl": null, 
    "success": false, 
    "error": { 
     "code": 0, 
     "message": "Current user did not login to the application!", 
     "details": null, 
     "validationErrors": null 
    }, 
    "unAuthorizedRequest": true, 
    "__abp": true 
} 

當用戶登錄,那麼一切都OK。 我想在WPF客戶端中獲得相同的JSON。我做錯了什麼?

public virtual async Task<TResult> GetAsync<TResult>(string url, int? timeout = null, params NameValue[] urlParameters) 
     where TResult : class 
{ 
    var cookieContainer = new CookieContainer(); 

    using (var handler = new HttpClientHandler { CookieContainer = cookieContainer }) 
    { 
     using (var client = new HttpClient(handler)) 
     { 
      client.Timeout = timeout.HasValue ? TimeSpan.FromMilliseconds(timeout.Value) : Timeout; 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      foreach (var header in RequestHeaders) 
      { 
       client.DefaultRequestHeaders.Add(header.Name, header.Value); 
      } 

      foreach (var cookie in Cookies) 
      { 
       if (!string.IsNullOrEmpty(BaseUrl)) 
       { 
        cookieContainer.Add(new Uri(BaseUrl), cookie); 
       } 
       else 
       { 
        cookieContainer.Add(cookie); 
       } 
      } 

      var uri = new Uri(BaseUrl).AddPathSegment(url); 
      var urlBuilder = new UriBuilder(uri); 

      if (urlParameters != null && urlParameters.Any()) 
      { 
       BuildUrlParametersString(urlBuilder, urlParameters); 
      } 

      using (var response = await client.GetAsync(urlBuilder.Uri)) // <--- Exception here 
      { 
       SetResponseHeaders(response); 
       GenerateExceptionOnBadStatus(response, urlBuilder.ToString()); 

       var ajaxResponse = JsonString2Object<AjaxResponse<TResult>>(await response.Content.ReadAsStringAsync()); 

       if (!ajaxResponse.Success) 
       { 
        Generateexception(ajaxResponse); 
       } 

       return ajaxResponse.Result; 
      } 
     } 
    } 
} 

服務器日誌:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 
     Request starting HTTP/1.1 GET http://localhost:62114/api/User 
info: Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor[1] 
     Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext. 
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 
     Executed action PAG.Identity.Web.Api.UsersContoller.GetAll (PAG.Identity.Web.Mvc) in 870.4395ms 
fail: Microsoft.AspNetCore.Server.Kestrel[13] 
     Connection id "0HL8JLDUTGR59", Request id "0HL8JLDUTGR59:00000001": An unhandled exception was thrown by the application. 
Abp.Authorization.AbpAuthorizationException: Текущий пользователь не вошёл в приложение! 
    at Abp.Authorization.AuthorizationHelper.<AuthorizeAsync>d__19.MoveNext() in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 43 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Abp.Authorization.AuthorizationHelper.<CheckPermissions>d__22.MoveNext() in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 98 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Abp.Authorization.AuthorizationHelper.<AuthorizeAsync>d__20.MoveNext() in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 57 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot) 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task) 
    at Nito.AsyncEx.AsyncContext.Run(Func`1 action) 
    at Abp.Authorization.AuthorizationInterceptor.Intercept(IInvocation invocation) in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationInterceptor.cs:line 20 
    at Castle.DynamicProxy.AbstractInvocation.Proceed() 
    at Microsoft.AspNetCore.Mvc.Controller.Dispose() 
    at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.ApplyConcerns(IEnumerable`1 steps, Object instance) 
    at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Destroy(Object instance) 
    at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Release(Object instance) 
    at Castle.MicroKernel.Burden.Release() 
    at Castle.MicroKernel.Releasers.LifecycledComponentsReleasePolicy.Release(Object instance) 
    at Castle.Windsor.MsDependencyInjection.MsLifetimeScope.DisposeInternal() in D:\Github\castle-windsor-ms-adapter\src\Castle.Windsor.MsDependencyInjection\MsLifeTimeScope.cs:line 108 
    at Microsoft.AspNetCore.Hosting.Internal.RequestServicesFeature.Dispose() 
    at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.<ProcessRequestsAsync>d__2.MoveNext() 
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 
     Request finished in 1055.3429ms 401 application/json; charset=utf-8 

更新

我認爲這個問題是因爲我用的AbpAuthorize代替AbpMvcAuthorize屬性我控制器。現在的問題是:我得到了302,然後是404未經授權的請求。我認爲這是因爲IdentityAutomaticChallenge設置身份驗證,但我不知道如何禁用它。

+0

客戶端'IOException'中的錯誤信息是什麼? – aaron

+0

發生System.IO.IOException HResult = 0x80131620 消息=無法從傳輸連接讀取數據:連接已關閉。 源=系統 堆棧跟蹤: 在System.Net.ChunkParser.CompleteMetaDataReadOperation(的Int32 bytesRead) – Sergey

+0

你能儘量不要有'VAR response'在'using'聲明,看看是否在同一行發生錯誤? – aaron

回答

0

ASP.NET 1.x的核心

ABP版本2.x /模塊零核模板V2.X

修改IdentityRegistrar。核心項目:

// Before 
services.AddAbpIdentity<Tenant, User, Role>() 

// After 
services.AddAbpIdentity<Tenant, User, Role>(options => 
{ 
    options.Cookies.ApplicationCookie.AutomaticChallenge = false; 
}) 

參考:https://github.com/aspnet/Security/issues/804

ASP.NET Core 2.0

ABP 3.x版/模塊零核模板V3.0.0 - v3.4.0

修改AuthConfigurer.Web.Host項目:

// Before 
services.AddAuthentication() 

// After 
services.AddAuthentication(options => 
{ 
    options.DefaultAuthenticateScheme = "JwtBearer"; 
    options.DefaultChallengeScheme = "JwtBearer"; 
}) 

參考:92b6270模塊-zero-core-template v3.5.0

相關問題