在单声道上使用owin auth时找不到方法'HttpRequestBase.GetBufferlessInputStream'

时间:2015-09-26 09:35:40

标签: asp.net mono asp.net-web-api2 owin

我在运行mono 4.3.0的CentOS服务器上部署了一个Asp.Net Web API项目(由2天前发布的mono-4.2.1.36分支编译)。我使用VS2015 enpty web api模板构建了项目,并添加了owin身份验证,试图通过使用bearer令牌获取web api进行身份验证。

我正在使用mod_mono在apache服务器上托管项目。

在我的Windows机器上本地运行项目时,一切都很完美。在Linux上,当我向/ token端点发送http POST时,服务器返回200 OK,但没有任何响应有效负载(其中包括客户端需要对后续请求进行身份验证的承载令牌)。同时,服务器记录异常(以下)。

System.MissingMethodException: Method 'HttpRequestBase.GetBufferlessInputStream' not found.
  at Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream.get_Stream () <0xb0e339b8 + 0x00013> in <filename unknown>:0
  at Microsoft.Owin.Host.SystemWeb.CallStreams.DelegatingStream.get_CanRead () <0xb0e45eb0 + 0x00013> in <filename unknown>:0
  at System.IO.StreamReader..ctor (System.IO.Stream stream, System.Text.Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen) <0xb0e5d790 + 0x0005f> in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) System.IO.StreamReader:.ctor (System.IO.Stream,System.Text.Encoding,bool,int,bool)
  at Microsoft.Owin.OwinRequest+<ReadFormAsync>d__0.MoveNext () <0xb0e33510 + 0x000f3> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0xb0e34a68 + 0x0002b> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0xb0e346d0 + 0x000bb> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0xb0e34588 + 0x0007f> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0xb270df98 + 0x00033> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0xb270e1d0 + 0x00017> in <filename unknown>:0
  at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler+<InvokeTokenEndpointAsync>d__22.MoveNext () <0xb0e2f118 + 0x00463> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0xb0e34a68 + 0x0002b> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0xb0e346d0 + 0x000bb> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0xb0e34588 + 0x0007f> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0xb270df98 + 0x00033> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () <0xb270df70 + 0x00013> in <filename unknown>:0
  at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler+<InvokeAsync>d__0.MoveNext () <0xb270e790 + 0x007a7> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0xb0e34a68 + 0x0002b> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0xb0e346d0 + 0x000bb> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0xb0e34588 + 0x0007f> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0xb270df98 + 0x00033> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0xb270f5b0 + 0x00013> in <filename unknown>:0
  at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1+<Invoke>d__0[TOptions].MoveNext () <0xb270b2a0 + 0x0030f> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0xb0e34a68 + 0x0002b> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) <0xb0e346d0 + 0x000bb> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) <0xb0e34588 + 0x0007f> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) <0xb270df98 + 0x00033> in <filename unknown>:0
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () <0xb270df70 + 0x00013> in <filename unknown>:0
  at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage+<RunApp>d__5.MoveNext () <0xb270aa98 + 0x00173> in <filename unknown>:0

在谷歌搜索后,我发现此异常已在另一个命名空间中修复,但请注意,这来自Microsoft.Owin.Host.SystemWeb。

是否有解决方法来摆脱异常,并且是否有人有关于该异常是否是我正面临的行为的原因的信息,或者是否有其他我可以尝试以获得基于承载令牌的身份验证工作?

在我的AuthorizationServerProvider中,我实现了以下方法: (另外,在Linux上运行时,响应头不包括Access-Control-Allow-Origin,就像在Windows上一样)

public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
  context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
  context.Validated();
  return Task.FromResult<object>(null);
}

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    //check credentials

    var identity = new ClaimsIdentity(context.Options.AuthenticationType);
    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); //etc

    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
       { "as:client_id", (context.ClientId == null) ? string.Empty : context.ClientId },
       { "userName", context.UserName }
    });

    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
}

public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
    foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
    {
        context.AdditionalResponseParameters.Add(property.Key, property.Value);
    }

    return Task.FromResult<object>(null);
}

我的Startup.cs看起来像这样:

public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);

    HttpConfiguration config = new HttpConfiguration(); 
    config.Filters.Add(new AuthorizeAttribute());
    WebApiConfig.Register(config); 

    GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    GlobalConfiguration.Configuration.Filters.Add(new AuthorizeAttribute());

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  
    app.UseWebApi(config);
}

public void ConfigureOAuth(IAppBuilder app)
{
    OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(15),
        Provider = new BoaAuthorizationServerProvider(),

        RefreshTokenProvider = new BoaRefreshTokenProvider(),
        ApplicationCanDisplayErrors = true,
    };
    // Enable the application to use bearer tokens to authenticate users
    app.UseOAuthBearerTokens(OAuthServerOptions);
}

编辑:

有关此内容的更多信息:

我尝试了旧的remove-the-problematic-dll -trick,我不再获得该异常,但是当我向客户端发送一个http POST时,我确实收到了500内部服务器错误(同样有效)在窗户上。)

这是一个例外:

System.Web.HttpException
Method 'POST' is not allowed when accessing file '/webapitest/token'

Description: HTTP 500.Error processing request.
Details: Error processing request.
Exception stack trace:
   at System.Web.DefaultHttpHandler.BeginProcessRequest (System.Web.HttpContext context, System.AsyncCallback callback, System.Object state) in <filename unknown>:line 0
   at System.Web.HttpApplication+<Pipeline>c__Iterator1.MoveNext () in <filename unknown>:line 0
   at System.Web.HttpApplication.Tick () in <filename unknown>:line 0

请注意上面的启动配置,单声道不支持的是什么?如果没有,这似乎是一个配置问题或单声道中的错误,因为有人先前评论说他们得到了与Ubuntu上发生的GetBufferlessInputStream相同的MissingMethodException。那条评论已被删除。

1 个答案:

答案 0 :(得分:0)

此错误仍在从官方存储库下载的单声道版本中重现(似乎正确的GetBufferlessInputStream&amp; GetBufferedInputStream在该提交中实现: 303d876370017774445c71736cf34e851e5cb037)。

对我来说最简单的方法是从nightlybuild repo更新依赖库(不需要编译整个项目并仅更新所需的库以节省磁盘空间)。 更新Debian的说明:

echo "deb http://download.mono-project.com/repo/debian nightly main" | sudo tee /etc/apt/sources.list.d/mono-nightly.list
sudo apt-get update
sudo apt-get install libmono-system-net-http-webrequest4.0-cil

(任何其他libmono http库也应该工作,所需包的列表将自动组合)