Acquire Twitter request token failed - c#

I followed the instruction at http://dev.twitter.com/pages/auth#request-token, and developed a c# class to do the OAuth authorization. I used the parameters on the page, and the output signature base string and signature match that on the page. So I think the algorithm part is correct. Then I replaced the parameters with the ones in my twitter application, but I failed to acquire the request token from Twitter service. And the response data is "Failed to validate oauth signature and token".
Here's the request I send (I used http, instead of https for debug):
POST http://api.twitter.com/oauth/request_token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_callback="http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_nonce="QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272323042", oauth_version="1.0", oauth_signagure="IP%2FEEoc4tKdiobM%2FKH5cPK69cJM%3D"
Host: api.twitter.com
Proxy-Connection: Keep-Alive
And here's the response:
HTTP/1.1 401 Unauthorized
Connection: Keep-Alive
Connection: Proxy-Support
Content-Length: 44
Via: 1.1 APS-PRXY-09
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Date: Fri, 08 Apr 2011 05:47:20 GMT
Content-Type: text/html; charset=utf-8
Server: hi
Proxy-Support: Session-Based-Authentication
Status: 401 Unauthorized
X-Transaction: 1302241640-40339-46793
Last-Modified: Fri, 08 Apr 2011 05:47:20 GMT
X-Runtime: 0.01519
Pragma: no-cache
X-Revision: DEV
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Set-Cookie: k=207.46.55.29.1302241640766556; path=/; expires=Fri, 15-Apr-11 05:47:20 GMT; domain=.twitter.com
Set-Cookie: guest_id=13022416407746962; path=/; expires=Sun, 08 May 2011 05:47:20 GMT
Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCEiBpjMvAToHaWQiJWMzMTViOGZiNDkzMDRi%250ANjNhMmQwYmVkZDBhNTc2NTc4IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--177afd5c0f6fe30005ab9a9412e6f85ab03cbfa7; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding
Failed to validate oauth signature and token
This is how I generate the normalized parameters:
string.Join("&", (from d in this.BuildParameterDict()
select string.Format("{0}={1}", OAuthEncoding.Encode(d.Key), OAuthEncoding.Encode(d.Value))))
The BuildParameterDict method will sorted build a list with: parameters from query string; parameters from body; parameters sepcific to 'oauth', except the 'oauth_signature'.
Then the signature base string is generated by:
StringBuilder sb = new StringBuilder();
sb.Append(OAuthEncoding.Encode(this._request.Method));
sb.Append('&');
sb.Append(OAuthEncoding.Encode(this.GetNormalUri()));
sb.Append('&');
sb.Append(OAuthEncoding.Encode(this.GetNormalParameters()));
This is the generated base string with parameters from the above page:
POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Flocalhost%253A3005%252Fthe_dance%252Fprocess_callback%253Fservice_provider_id%253D11%26oauth_consumer_key%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3DQP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272323042%26oauth_version%3D1.0
which is identical to the string on that page.

Your oauth signature is listed as "oauth_signagure" in your request.
oAuth parameters has to be sorted before sending, but signature has to be at the end of the authorization request.(9.1.1 in http://oauth.net/core/1.0/#anchor14)
You may also need to specify a realm="/oauth/request_token". It's optional, but as I remember correctly Twitter wants this one for a request token.
If you can add your code we might find what's going on, as you might not be building your request and key for signature hashing correctly.

Related

I get a Bad request Status Code 400 when I am trying to consume a REST API online using C#

I am working with REST APIs and trying to connect to a REST API online that I can get to fine via the browser but when I try with some simple code, it is failing:
var client = new HttpClient();
var uri = new Uri("http://dummy.restapiexample.com/api/v1/employee/1");
try
{
var response = client.GetAsync(uri).Result;
if (response.IsSuccessStatusCode)
{
Console.WriteLine(response.Content.ReadAsStringAsync());
}
else
{
Console.WriteLine($"{response.StatusCode} - {response.ToString()}");
}
}
catch (Exception ex)
{
Console.WriteLine(#"\tERROR {0}", ex.Message);
}
The response message I get is the following:
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Type, X-Requested-With, X-authentication, X-client
Host-Header: c2hhcmVkLmJsdWVob3N0LmNvbQ==
Pragma: no-cache
Referrer-Policy:
Response: 400
Cache-Control: no-cache
Date: Fri, 10 Apr 2020 10:38:39 GMT
Set-Cookie: PHPSESSID=a8474e93077d190fe6bcdcb1ae1cbd42; path=/
Set-Cookie: ezoadgid_133674=-1; Path=/; Domain=restapiexample.com; Expires=Fri, 10 Apr 2020 11:08:39 UTC
Set-Cookie: ezoref_133674=; Path=/; Domain=restapiexample.com; Expires=Fri, 10 Apr 2020 12:38:39 UTC
Set-Cookie: ezoab_133674=mod58-c; Path=/; Domain=restapiexample.com; Expires=Fri, 10 Apr 2020 12:38:39 UTC
Set-Cookie: active_template::133674=pub_site.1586515119; Path=/; Domain=restapiexample.com; Expires=Sun, 12 Apr 2020 10:38:39 UTC
Server: nginx/1.16.0
Vary: Accept-Encoding
Vary: Accept-Encoding
Vary: User-Agent
Vary: X-APP-JSON
X-Ezoic-Cdn: Miss
X-Middleton-Response: 400
X-Sol: pub_site
Content-Length: 75
Content-Type: application/json; charset=utf-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
}
Can someone point me in the right direction as to how I can fix this?
The problem appears to be with the REST API itself, because when I used the following REST API https://jsonplaceholder.typicode.com/todos/1 it worked fine.

OneNote API - Cannot get Pages

I have been playing around with the OneNote API, and have been successful at getting Notebooks,Sections,Pages.
Today however I have been unsuccessful getting the pages using the Section.pagesUrl.
My Request: https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!19161/pages
Where 0-2B36C9469D6FE2E!19161 is the ID of the section.
This has worked before, but has somehow stopped working.
Right before this request I successfully get the Notebooks, then once finding correct notebook from the returned list, get the sections and again find the correct section.
The response I am getting is 200(OK) but an empty array:
{
"#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/sections('0-2B36C9469D6FE2E%2119161')/pages",
"value":[
]
}
Although I can see the same Notbooks and Sections in my OneNote client. And sections do have pages. But I am not getting them any more.
Any reason why this could be happening?
Could it be a bug on your side or is there something I'm missing?
I add the Bearer token to the HttpClient like so:
_client = new HttpClient();
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _tokenService.AccessToken);
Which seemed to work last week, and it is still working for getting Notebooks/Sections
EDIT: Requests + Responses
Request that works (getting sections):
GET https://www.onenote.com/api/v1.0/notebooks/0-2B36C9469D6FE2E!19159/sections HTTP/1.1
Authorization: Bearer EwB4Aq1DBAAUGCCXc8wU/zFu9QnLdZXy+YnElFkAAV1uu7Y2xsmzQFS/JyikQRMlK3+hurlsMQZTiYaefQ5ZVjZnnsB5bAeXFSUAGmNw4/B7DBk/tbjwWw5WzBFv0wdJERyLqCXU42WfpDKuHeZXZVS1p14teY0dr7OzN+G10Fn3/grWeHiRISlAqCBh6vV+qEO+11kFhxiCjERey6BJrMJVMCzMundN59uDM/jj8jJ9T7q2LlMqZQXFYra+DfrxWGCPzNMaJMRQYDpwrmov3kZlx2ZfL+k8Hv7luK7euEztfj5iTD4sJBCC2dURdysJdI//R0YRf5do94MyP2FD9dsLwhbl9qEhuJ+nxfVCja+s3d+GXggOBr29ivzbLYQDZgAACIabXCL9fNi6SAHeSujyYzD8QQdsytnb8nc2noza9JEWKr/tGHn2G/SofZBYrMEZCx5PBAKWghhWY40z2TCnD6MRgyFSBoqbGimNOkb7/vMHPgBUKJrxIgCgJmbW15IuYkZ11j7CK5+/JYyk+ufIjA8VEdl+HjDaUi35Hd9n8919XpQmHSH9aIZc8reC/7L90b5flE01i/ngXjuntxH92MKPm92+WVDuN9d4QWez6YEYpsBgynpx6BP8PfNbhu1E1LZUa9ZnwdBA1Pw0oYvC8jvfhx8bDhnZc2YMEQo/0XZSx5WUdVbBQfmU8gbQD86Ms3hm6fSVXxzzHIvMy0WR5Wpqr4A3+amUNFp6EApcCRI0Ydf+VLmiHHNcKWHGRaSUFDRsmaSlmmrQiBATtG4wJihywrkePrT4OBaJD/jVH9FvIZrLa33POSN1CLcFXlbKezyAYwE=
Accept: application/json
Host: www.onenote.com
Response:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.5
X-CorrelationId: d3c85fde-c8e0-4e4e-a4df-87a3f57f146e
X-UserSessionId: d3c85fde-c8e0-4e4e-a4df-87a3f57f146e
X-OfficeFE: OneNoteServiceFrontEnd_IN_0
X-OfficeVersion: 16.0.6023.1561
X-OfficeCluster: neu-www.onenote.com
P3P: CP="CAO DSP COR ADMa DEV CONi TELi CUR PSA PSD TAI IVDi OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR"
X-Content-Type-Options: nosniff
Request-Processing-Time: 828.1859 ms
OData-Version: 4.0
Preference-Applied: odata.include-annotations=*
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 25 Jul 2015 12:10:58 GMT
Content-Length: 3135
{
"#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections(parentNotebook(id,name,self),parentSectionGroup(id,name,self))","value":[
{
"isDefault":false,"pagesUrl":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!41276/pages","name":"Agily","createdBy":"LnDSoft Test","lastModifiedBy":"LnDSoft Test","lastModifiedTime":"2015-07-23T11:39:46.9Z","id":"0-2B36C9469D6FE2E!41276","self":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!41276","createdTime":"2015-07-15T23:39:22.44Z","parentNotebook#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2141276')/parentNotebook(id,name,self)/$entity","parentNotebook":{
"id":"0-2B36C9469D6FE2E!19159","name":"Agily","self":"https://www.onenote.com/api/v1.0/notebooks/0-2B36C9469D6FE2E!19159"
},"parentSectionGroup#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2141276')/parentSectionGroup(id,name,self)/$entity","parentSectionGroup":null
},{
"isDefault":false,"pagesUrl":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!19161/pages","name":"AgilyTest","createdBy":"LnDSoft Test","lastModifiedBy":"M C","lastModifiedTime":"2015-07-21T23:16:18.85Z","id":"0-2B36C9469D6FE2E!19161","self":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!19161","createdTime":"2015-01-04T23:50:32.41Z","parentNotebook#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2119161')/parentNotebook(id,name,self)/$entity","parentNotebook":{
"id":"0-2B36C9469D6FE2E!19159","name":"Agily","self":"https://www.onenote.com/api/v1.0/notebooks/0-2B36C9469D6FE2E!19159"
},"parentSectionGroup#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2119161')/parentSectionGroup(id,name,self)/$entity","parentSectionGroup":null
},{
"isDefault":false,"pagesUrl":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!41275/pages","name":"OtherSection","createdBy":"LnDSoft Test","lastModifiedBy":"LnDSoft Test","lastModifiedTime":"2015-07-15T23:36:15.037Z","id":"0-2B36C9469D6FE2E!41275","self":"https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!41275","createdTime":"2015-07-15T23:35:13.9Z","parentNotebook#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2141275')/parentNotebook(id,name,self)/$entity","parentNotebook":{
"id":"0-2B36C9469D6FE2E!19159","name":"Agily","self":"https://www.onenote.com/api/v1.0/notebooks/0-2B36C9469D6FE2E!19159"
},"parentSectionGroup#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/notebooks('0-2B36C9469D6FE2E%2119159')/sections('0-2B36C9469D6FE2E%2141275')/parentSectionGroup(id,name,self)/$entity","parentSectionGroup":null
}
]
}
Request that does not work (getting pages, using the URL from above):
Request:
GET https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!19161/pages HTTP/1.1
Authorization: Bearer EwB4Aq1DBAAUGCCXc8wU/zFu9QnLdZXy+YnElFkAAV1uu7Y2xsmzQFS/JyikQRMlK3+hurlsMQZTiYaefQ5ZVjZnnsB5bAeXFSUAGmNw4/B7DBk/tbjwWw5WzBFv0wdJERyLqCXU42WfpDKuHeZXZVS1p14teY0dr7OzN+G10Fn3/grWeHiRISlAqCBh6vV+qEO+11kFhxiCjERey6BJrMJVMCzMundN59uDM/jj8jJ9T7q2LlMqZQXFYra+DfrxWGCPzNMaJMRQYDpwrmov3kZlx2ZfL+k8Hv7luK7euEztfj5iTD4sJBCC2dURdysJdI//R0YRf5do94MyP2FD9dsLwhbl9qEhuJ+nxfVCja+s3d+GXggOBr29ivzbLYQDZgAACIabXCL9fNi6SAHeSujyYzD8QQdsytnb8nc2noza9JEWKr/tGHn2G/SofZBYrMEZCx5PBAKWghhWY40z2TCnD6MRgyFSBoqbGimNOkb7/vMHPgBUKJrxIgCgJmbW15IuYkZ11j7CK5+/JYyk+ufIjA8VEdl+HjDaUi35Hd9n8919XpQmHSH9aIZc8reC/7L90b5flE01i/ngXjuntxH92MKPm92+WVDuN9d4QWez6YEYpsBgynpx6BP8PfNbhu1E1LZUa9ZnwdBA1Pw0oYvC8jvfhx8bDhnZc2YMEQo/0XZSx5WUdVbBQfmU8gbQD86Ms3hm6fSVXxzzHIvMy0WR5Wpqr4A3+amUNFp6EApcCRI0Ydf+VLmiHHNcKWHGRaSUFDRsmaSlmmrQiBATtG4wJihywrkePrT4OBaJD/jVH9FvIZrLa33POSN1CLcFXlbKezyAYwE=
Accept: application/json
Host: www.onenote.com
Response:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.5
X-CorrelationId: fe872c95-f8af-41e3-b019-4e6504a5e8df
X-UserSessionId: fe872c95-f8af-41e3-b019-4e6504a5e8df
X-OfficeFE: OneNoteServiceFrontEnd_IN_0
X-OfficeVersion: 16.0.6023.1561
X-OfficeCluster: neu-www.onenote.com
P3P: CP="CAO DSP COR ADMa DEV CONi TELi CUR PSA PSD TAI IVDi OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR"
X-Content-Type-Options: nosniff
Request-Processing-Time: 703.1688 ms
OData-Version: 4.0
Preference-Applied: odata.include-annotations=*
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 25 Jul 2015 12:10:58 GMT
Content-Length: 143
{
"#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/sections('0-2B36C9469D6FE2E%2119161')/pages","value":[
]
}
EDIT 2: Still not working
Request:
GET https://www.onenote.com/api/v1.0/sections/0-2B36C9469D6FE2E!19161/pages HTTP/1.1
Authorization: Bearer EwCAAq1DBAAUGCCXc8wU/zFu9QnLdZXy+YnElFkAAZdDnoj6ATyof3wJ8jfSPNcSx+uxW4fVURSJ29iChWlIuhitDH11wKItykmBolKwHRyINjz4+dknXJcNfHgGv6R7AOpSeuNt/lr+h/9HUS20/aV0/NssaoXh7lyGKQekX22D+KtcprNi9zoXbtR6t07tz7aHyx3V7F4qHQVZmG2psWTGVpwa/TTCLB4jgDCEHwQYV9XgjGnpIJgyIZvmI+hZ0DRkBF9gyp49BMNrgdi75jLyfecbYU1MaxBdaUQuhZFXjGEv8pMecsscGcLM9JvbtT6Ap6k6mQv5D6GeCe/CHxgQO+3IoXXRLG/n61eGHpf8/WbQorzeCDnbbtcSkCYDZgAACPGa/3ibM+sXUAHc/d8IiDQnNRQHYfY/sl7b179y4gRsnP5YUN7dI7CkNkFR4sSWo1Db9tBmZN3bA4LN94D4GEzDhegNrjXtm5NFrrhrGOInZzFxtlfRVa1GvgPgPc2s8clOacwE5zi2jr1SSf39AfJjBYfMK2ePYN8XRdzjBMfAXZFHv0MOIk3pAbE/Tk0YSPqRk1whxHrLFxkYvk5PI8IoWsyKIUudp7B2GwvWAE2WycX2P49yJs4qZ/+Ocu/k0jJv16kUa/szN4G8lmcEZykiKrLgGFxZbfKn8L9/sECD7Wj5X0pxH4aDnvUrcjsFNrreanAeG+KyLsHdhOL3UIy/uiLRsarLsdXmlUV2JGHdGiAdZ53wR+xKOYq7xoBP7myhxIoFoqnm7wVnKi8+2CiA8T9y+JtVToQMxjTD1xacuuZ8malpifqTTHYYXmggOaukHOcsV0TQz4JjAQ==
Accept: application/json
Host: www.onenote.com
Response:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.5
X-CorrelationId: 7cb781ec-36d4-4485-b6c1-a48f7e536298
X-UserSessionId: 7cb781ec-36d4-4485-b6c1-a48f7e536298
X-OfficeFE: OneNoteServiceFrontEnd_IN_5
X-OfficeVersion: 16.0.6023.1561
X-OfficeCluster: neu-www.onenote.com
P3P: CP="CAO DSP COR ADMa DEV CONi TELi CUR PSA PSD TAI IVDi OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR"
X-Content-Type-Options: nosniff
Request-Processing-Time: 671.9287 ms
OData-Version: 4.0
Preference-Applied: odata.include-annotations=*
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 28 Jul 2015 02:21:40 GMT
Content-Length: 143
{
"#odata.context":"https://www.onenote.com/api/v1.0/$metadata#me/notes/sections('0-2B36C9469D6FE2E%2119161')/pages","value":[
]
}
You can see in the below screenshot that pages exist
for Agily (Notebook) -> Agily (Section)
I have been investigating this issue for you today. I was wondering if you could try this request again?
Our storage layer experienced some failures over the weekend that could possibly explain the issue so I wanted to verify with you that you are seeing the issue still.
As far as I can tell from the request that you posted and the logs on our end, there is nothing wrong syntactically with the request and no obvious logic errors on our end, so the investigation is currently pointing at the storage layer as possibly being the culprit.
Thanks,
Daniel

HttpResponseMessage with Unauthorize status code and Content // response without required WWW-Authenticate header field

Using ASP.NET Web API 2, if I want to return HttpResponseMessage with Unauthorized status code, I'll get different response headers - with or without WWW-Authenticate header field - depending on whether this response message has content or not.
WWW-Authenticate header field is a required field for Unauthorized response according to Status Code Definitions.
And the lack of WWW-Authenticate header field in the response causes an error for the next request.
To see the problem you can create a new Web API project and to add a simple test controller:
public class TestController : ApiController
{
public HttpResponseMessage Get()
{
var responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
// Content = new StringContent("You are not authorized"),
};
return responseMessage;
}
}
If the response message doesn't have a content we'll get normal 401 responses for our calls:
With responses:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Bearer
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:31:20 GMT
Content-Length: 0
If we add content to the response message (uncomment the content line), each second response will be not 401, but 500
The responses with 401 will have the following headers:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 22
Content-Type: text/plain; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:34:38 GMT
You are not authorized
And the responses with 500 will say
Server cannot append header after HTTP headers have been sent.
Description: an unhandled exception occurred during the execution of the current web request.Please review the stack trace for more information about the error and where it originated in the code..... Exception Details: System.Web.HttpException: Server cannot append header after HTTP headers have been sent.
So it looks like it happens because previous responses are illegal - they don't contain WWW-Authenticate header attribute.
But it doesn't help even if I try to add WWW-Authenticate manually
public class TestController : ApiController
{
public HttpResponseMessage Get()
{
var responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("You are not authorized"),
};
responseMessage.Headers.Add("WWW-Authenticate", "Bearer");
return responseMessage;
}
}
Now it's in the response
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 22
Content-Type: text/plain; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:43:51 GMT
You are not authorized
but I still have every second request 500 instead of 401.
Can anyone clarify what's going on here and how to make it work properly?
The Server cannot append header after HTTP headers have been sent. error message from the response with 500 is caused by a module trying to write http headers into the response stream once your action has executed - since your action has already written both the headers and the body.
The usual culprits are FormsAuthentication and Owin cookie authentication kicking in and trying to replace 401 with 302 (redirect to login page).
Scenario:
1. your action executed - added header 401 Unauthorized to the headers collection plus wrote the header into the response stream and then wrote the body (You are not authorized) to the response stream.
2. FormsAuthenticationModule sees 401 Unauthorized header in the response headers collection and attempts to change that to 302 Redirect to login page, plus attempts to write the corresponding header to the response stream - which fails with Server cannot append header after HTTP headers have been sent., since the headers were already written earlier.
Possible fixes:
1) if FormsAuthenticationModule is in your request pipeline
consider disabling it if you are not using it
in .net 4.5 you you can suppress forms authentication redirection by setting HttpResponse.SuppressFormsAuthenticationRedirect property to false
if not on .net 4.5, consider using HttpModule which will suppress this redirection
Phil Haack blogged on all the above options.
2) if using OWIN cookie authentication - consider not setting LoginPath property

Google Drive: Error in retrieving access and refresh tokens

I am trying to access google drive from my app for WP7. But when i try to get access token in exchange for Authorization code, I get BAD REQUEST from server.
My POST request as seen in Fidler:
POST https://accounts.google.com/o/oauth2/token HTTP/1.1
Accept: */*
Referer: file:///Applications/Install/7128457C-3AF4-41C4-A606-742068B1463F/Install/
Content-Length: 240
Accept-Encoding: identity
Content-Type: application/x-www-form-urlencoded
User-Agent: NativeHost
Host: accounts.google.com
Connection: Keep-Alive
Cache-Control: no-cache
code=<*Authorization_Code*>&
client_id=<*My_Client_Id*>&
client_secret=<*My_Client_Secret*>&
redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&
grant_type=authorization_code
Response from server:
HTTP/1.1 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Sat, 07 Sep 2013 14:05:35 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic
Transfer-Encoding: chunked
21
{
"error" : "invalid_request"
}
0
My Code:
StringBuilder postData = new StringBuilder();
postData.AppendFormat("{0}={1}", "code", HttpUtility.UrlEncode(AuthorizationCode));
postData.AppendFormat("&\n{0}={1}", "client_id", HttpUtility.UrlEncode(ClientId));
postData.AppendFormat("&\n{0}={1}", "client_secret", HttpUtility.UrlEncode(ClientSecret));
postData.AppendFormat("&\n{0}={1}", "redirect_uri", HttpUtility.UrlEncode("urn:ietf:wg:oauth:2.0:oob"));
postData.AppendFormat("&\n{0}={1}", "grant_type", HttpUtility.UrlEncode("authorization_code"));
WebClient client = new WebClient();
client.UploadStringCompleted += TokenResponse;
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
client.UploadStringAsync(new Uri("https://accounts.google.com/o/oauth2/token",UriKind.Absolute), "POST", postData.ToString());
I get this result both on emulator as well as Lumia 820. I also tried without using HttpUtility in POST request but didn't work. Any help?
Its likely due to the fact that you are adding a new line via \n between all the param/value pairs.
I do it without that without it and it works - https://github.com/entaq/GoogleAppsScript/blob/master/IO2013/YouTubeAnalytics/oauth2.gs#L25

Why is one cookie missed?

I'm scrapping a page which is the result of a redirect: I visit page1 first, then it redirects to page2 via http-equiv="refresh". I'm scrapping page2. Content on page2 is based on some cookies page1 sets. I see page1 returns 2 cookies, but when I request page 2 (sending the same CookieContainer, one cookie is missing. What's wrong in my code?
Thank you:
First :
I create a CookieContainer and an HttpWebRequest and request for page1.
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(eQuery);
req.AllowAutoRedirect = true; // but it doesn't autoredirects the meta-refresh
req.CookieContainer = cookiesContainer;
This is the result I get this from visiting page1
HTTP/1.1 200 OK
Date: Tue, 12 Apr 2011 19:14:06 GMT
Server: (...)
Set-Cookie: NAME1=VALUE1; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: NAME2=VALUE2; expires=Wed, 13-Apr-2011 19:14:06 GMT
Content-Length: 174
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
(...)
Everything is fine so far, I get two cookies are there and I get two cookie objects within the container.
Then I parse the "content" value of the meta http-equiv for the next url. And request it using a similar code and using the same container. But only one cookie is sent. Here is the HTTP sent:
GET DETECTED_URL_IN_HTTP_EQUIV_REFRESH HTTP/1.1
User-Agent: (...)
Host: example.com
Cookie: NAME1=VALUE1
As you see cookie NAME2 is missing. Why is that happening? is something related differences in the two cookies (one has path and other has expiration date)?
Any idea how can I pass the two cookies?
PS: I don't have access to page1, so I can't set path, or expiration for cookies. I'm scrapping those pages.
Thank you.
If you don't specify a path on your cookie it will default to the path it was requested on. So if you received a cookie on this request with no path declaration:
http://contoso.com/subfolder/test.aspx
The browser would only send back that cookie for more requests in the /subfolder/ directory. To have the browser send it back for all paths you need to include path=/ when setting the cookie.

Categories