-
-
Notifications
You must be signed in to change notification settings - Fork 764
Issue in 2.0.0-beta6 - CopyToAsync of InputStream (OWIN) #1533
Comments
Going a bit down the rabbit hole... Grab the source again and found where the issue is occurring. Deep inside InternalOwinExtensions.cs in ReadRequestFormAsync, the CopyToAsync is producing an empty memory stream even though the input stream has content.
|
I confirmed and repro'd it on another workstations. Very odd. Certainly not IdentityServer issue but still very odd.
|
I put in a patch so that I could keep working. I wrote a small Owin middleware that copies the inputstream to a memorystream and shoves it back into the request body. This memorystream is always seekable and thus bypasses the call to CopyToAsync. I am not sure if this is a framework, Owin or Azure compute emulator issue at this point but I need to move onto other things today and will try and revisit it tomorrow. UseIdentityServerExtension.cs
|
I spent another couple of hours on this and posted it to SO as well. Not entirely sure what is breaking it but it is reproducible even on a clean machine with the source I downloaded yesterday. At this point I need to move onto the problem I was solving at the time I encountered it. I will post here if I make any headway. |
Ok... and just to let you know, we've not been ignoring this -- it's just that I'm not sure what to say. Do the samples from our repo work for you? |
Brock, I had a couple of other ideas I wanted to try in the morning. Are there Jim On Thursday, June 25, 2015, Brock Allen notifications@github.com wrote:
|
The dev branch of samples is all up to date with the dev branch of Core (2.0.0) |
Brock, I tracked it down finally. It is in the logging code. In RequestResponseLogger.cs there is a destructive ReadAsStringAsync() on line 34. The reading of the content consumes the stream and then cannot be read (or copied) later.
Turing on/off EnableHttpLogging allows the issue to be reproduced. |
Ah, excellent find -- thanks! We'll get it fixed. |
Ok, I've pushed to the dev branch a potential fix. This will get pushed to myget -- do you mind testing against that build to see if this issue has been resolved? |
Sure thing. I have a couple of things going on first thing in the morning On Sunday, June 28, 2015, Brock Allen notifications@github.com wrote:
|
Brock, Everything is testing out well. I ran into an issue with the changes in the logging but I believe that is on my end at this point. I have to pull out my usage of the Diagnostic Trace Provider and rewire up my nLog implementation in order to get the verbose output I was seeing before but tokens are being generated. Thanks for all of your help. Jim |
Spoke too soon. If EnableHttpLogging is enabled it throws still. I did not catch it at first because it only occurs during an interactive login (I test client credentials). It might be in the validation code I mentioned in my email the other day. The MyGet package changed the way that I was logging and testing (BearTail). I am happy to grab the latest source and narrow this down as well if you wouldn't mind giving me a snippet to get my trace logging running again. |
Check the latest host on dev to see how tracing has changed in 2.0.0 |
So you're still having this issue? |
Yes, with the MyGet you asked me to test it did however I suspect not in On Sunday, July 5, 2015, Brock Allen notifications@github.com wrote:
|
I saw that it was removed but the entire LoggingProviders namespace is missing from the MyGet package. Do I have to roll my own or is there an example of Seri working? I see in the dev samples that there is a SeriLogProvider but the namespace does not exist in the package. |
just add SeriLog to the host - liblog picks that up automatically https://github.com/IdentityServer/IdentityServer3/blob/dev/source/Host/Startup.cs#L39 |
Thanks Dominick, that got me up and running. There was a conflict with how I had nLog implemented that was the root of the logging issue. With trace working I can see that with the latest MyGet package the error I am now encountering is with the validation of the AntiForgery token, not necessarily related to the initial problem though if the stream is being corrupted still it could be. Give me a few minutes to track down what changed in the AF code to see if it is related or if this issue can be closed out. |
I just grabbed the latest dev source. I realize I sound like a broken record however
on line 66 of ValidateAntiForgeryTokenAttribute.cs returns an empty byte array with HttpLogging enabled. I will see if I can find what is destructively reading the stream. |
It is a very similar issue to the one that kicked off this whole thread. I can see that you ran into a problem initially, the comment above the line of code that is failing says:
I went the route of pulling the body from the Owin context and while newing up the context works with the stream it produces, it likewise destroys the stream for the binding and therefore returns an invalid user/pass since the stream has been consumed. I am reproing this with the zip currently in the dev branch and will keep poking at it as time allows later today but I can confirm that I have a content length of 154 in my test setup and the call to ReadAsByteArrayAsync with HttpLogging enabled yields an empty byte array and subsequent failure to validate the anti-forgery token. |
Ok, perhaps MSFT changed something in Web API so that API no longer buffers? I'll see if I can change it to another OWIN abstraction. |
Actually, this shouldn't affect downstream copies of Web API. So yea, something's quite broken. It's upsetting that working purely at the OWIN level can't function across middlewares. I think this has something to do with 2 copies of Web API in the same pipeline -- the first one is draining the buffer at the host level. Not sure this will be something we can fix in IdSvr -- it's more of a Web API problem. I'll keep digging, though. |
Were you ever able to put a middleware in front of both that loaded the stream into a buffered stream at the OWIN layer? Then, in theory, all downstream consumption of that OWIN body stream will be from the buffered one. |
Yes, it is how I fixed it initially before I found the destructive stream On Monday, July 13, 2015, Brock Allen notifications@github.com wrote:
|
So I'd suggest going back to that -- that's cross middleware coordination that needs to happen and I'm not sure IdSvr should have then inside of its code (as it shouldn't have to be aware of other middleware). Again, this is fundamentally down to Web API as the issue. Also, I wonder why you're not using something more dynamic in each request to distinguish each copy of IdSvr? Like a Map or something else... IOW, should each one be looking at every request? |
I am only using one instance now and have been since you suggested it. On Monday, July 13, 2015, Brock Allen notifications@github.com wrote:
|
Is it possible that the issue is being caused by the web API I am hosting On Monday, July 13, 2015, James D. Legan jim@logicalnotion.com wrote:
|
Well, if they are all |
So I think we know the workaround -- the host would need middleware to buffer the OWIN request body stream. Thanks. |
Brock, I am okay with the solution I would just like to understand it a little bit. I am fairly certain I can repro this with a very simple implementation and if that is the case wouldn't it make more sense to have the buffering occur in the middleware of Idv3? My original middleware "fix" looked like this and I had put it in the Idv3 UseIdentityServerExtensions.cs
|
I'm not 100% sure really what the issue is either -- it's something between OWIN and Web API and multiple versions of Web API in the pipeline. As for the fix, we're sort of doing this in our internal APIs that read from the OWIN body. I guess it's Web API that's getting in the way. Perhaps our invocation of the Web API ReadBuffer is really the issue. Send me your repro and I'll see if I can figure it out. |
Brock, I have been engaged in a couple of projects but I have set a side a couple of hours tomorrow morning to make you as trim as possible of a solution starting with the current samples for 2.x. Sorry it is taking so long. Jim |
No worries -- I'm also quite busy myself. |
Brock, At the dropbox link below you will find a zip file. In it you have the following:
https://www.dropbox.com/sh/b33qihqborgvadg/AAABSRiBn96fosefgTea2A1Na?dl=0 A couple of things to note. I did not want to mess around with IIS Express and SSL so I used IIS on my end, you will likely want to switch that back on the Idv3 project. I also hard coded the URLs in the MVC project. To reproduce: Scenario 1: Leave "EnableHttpLogging" set to false, hit the "About" controller in the MVC app which has the authorize attribute. You will be redirected to Idv3, log in with the in-memory user "bob","bob". If you hit the consent screen you are good to go. Scenario 2: Turn on HttpLogging and once again hit the About controller. When you enter bob, bob you will immediately throw and arrive and the "unexpected error occurred" dialog in Idv3. To make it a bit easier for you I did not use the Idv3 nuget package in project 1 but rather included the latest Core project on dev so you can jump right into debugging it. The details below should illustrate where it gets pinched and even a possible solution in the middleware within Idv3 should you so choose to pursue it. Thanks for all of your help. Jim |
I never found time to look at your code, but I did make some related changes due to this thread: #1672. I'm hoping this will address your issue as well. |
It did not (2.0.0 RTM) |
that should be fixed now with 2.0.1 |
Took a bit too much out of the original description:
Moved over to 2.0.0-beta6 and started to receive unsupported_grant_types coming back from my hybrid flow call to request an auth code, mirroring the sample code.
I grabbed the source and debugged it and realized that not just the grant type but all params were missing even though they were making it to the identityserver. Below are my findings.
The text was updated successfully, but these errors were encountered: