.NET C# HttpClient read mutiple headers with same name - c#

I'm making a request to a third party web service that I have no control over.
The request provides a number of authentication components that come back as Headers named Set-Cookie
However the HttpResponseMessage.Headers collection only contains a single entry named Set-Cookie
How can I access the others?
Example of response headers:
Set-Cookie: username=*********; secure; HttpOnly; SameSite=Strict;SameSite=Lax
Set-Cookie: cust_id=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; SameSite=Strict; SameSite=Lax
Set-Cookie: auth_key=*************; expires=Mon, 23-Aug-2021 10:14:45 GMT; Max-Age=3600; secure; HttpOnly; SameSite=Strict; SameSite=Lax
Set-Cookie: ws_key=*************; secure; HttpOnly; SameSite=Strict; SameSite=Lax
Set-Cookie: ws_root=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; secure; SameSite=Strict; SameSite=Lax
Set-Cookie: impersonator=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; secure; SameSite=Strict; SameSite=Lax
The only one of the above which the Headers collection contains is:
auth_key=*************; expires=Mon, 23-Aug-2021 11:59:55 GMT; Max-Age=3600; secure; HttpOnly; SameSite=Strict; SameSite=Lax

Related

Azure Active Directory OpenID throwing nonce exception in web browser but not in web browser control

I am using OWIN authentication with OpenID to authenticate to an Azure AD endpoint. My application typically runs within a win-forms web-browser control and I am not experiencing any issues. But, when authenticating using a modern web browser I am getting a "nonce" exception in my Middleware Next.Invoke(context) in the response redirect from Azure Active Directory.
I have attached a fiddler of the response headers with the control and with the web browser. They are different but I am hoping for some insight as to why.
What differences between a web-browser control and a web browser might be causing this issue? And is there a resolution/ workaround?
This is successful with a web-browser control using IE 11 but has failed with IE 11, Edge, Chrome, and Firefox.
Note: The JWT does contain the nonce token in both situations, it is not being read in middleware.
I am using:
Microsoft.Owin.Security.OpenIdConnect, Version=4.0.1.0
Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.3.0.0
public class MyMiddleWare : OwinMiddleware
{
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
...
Error
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolInvalidNonceException
HResult=0x80131500
Message=IDX21323: RequireNonce is '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. OpenIdConnectProtocolValidationContext.Nonce was null, OpenIdConnectProtocol.ValidatedIdToken.Payload.Nonce was not null. The nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'. Note if a 'nonce' is found it will be evaluated.
Source=Microsoft.IdentityModel.Protocols.OpenIdConnect
StackTrace:
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidator.ValidateNonce(OpenIdConnectProtocolValidationContext validationContext)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidator.ValidateAuthenticationResponse(OpenIdConnectProtocolValidationContext validationContext)
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.<AuthenticateCoreAsync>d__9.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.<AuthenticateCoreAsync>d__9.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.<InvokeReplyPathAsync>d__16.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__7.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at ....<Invoke>d__5.MoveNext() in ...:line 29
Success
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: -1
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
x-ms-request-id: ffdb4ab7-a6b4-457e-b663-448727569900
x-ms-ests-server: 2.1.9524.8 - CHI ProdSlices
x-ms-clitelem: 1,0,0,228204.2529,
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
Set-Cookie: ESTSAUTHPERSISTENT=AQABAAQAACQN9QBRU3jT6bcBQLZNUj7jTNFH8tmqm9RCwduQg-S-Hg1JD5RJF6fmJ52lpVgyxkqYMpRP9IAURkUcO6yYTTJurmwF93DSyIr0GyvQmFO8ecuJra5gpBZcknhXnjHgMGZdW-IJg-maq9XPatsYpm_0vV7APXW89dnDq_rqOqXEIHYKBAUjAykyVlnq-2g0fN6UJhQbW0HcK78Fnu4ImfYqRWX7MmxILF3SXC9Ocmlphf22ThKPsZVJ2ZW7M7TaF7sBA94NokK75BWpOsYOeeBOX4VdJaJ3KQ2Qzx39cLNurZdlokZcv2QHhxif3FTBsFBlTRBeuHu2CZ5dRlG4n1DBRjCU4cgfXXkejKsQANLKGN3CFbZDPPlCfoZ3JVwrtWMCBUQRAnKI2k-CBgzY893M3dHHGdikMb6NfrlhIHxj7RUeVyeZNt655OYKz80SgEbsqOnXrEhs5uLipuotCCo0KlBD9c32N3wcEjtRcWccg5lhU9zj8j_BEmc0eDx-wWsayXyeFquHBUhtbi8nsaBzDyDwnr1m9JRfItjIy7CwmxmOkgdd0fs0I--Ge1qpFNq4dtcvN59iai9eBSPa6rU_iNFOwXcBvzickxhT5P9FQWEFtiXJqu2yCfiyr29nk_3lnERJmPKvH7w9mNhNOZhY1gftaYKRa41RVCaFvDZxJHYjHP5-Zt8kD9POHc6Q1DKF9auL2C6tH60UHPXyeaNb1WpVq_cni_RJ4b7IvsTni9fDhFWvBSgOdoIdfrXj6oO6KhkBX-IjIJ21NirfXGxLLYo_xU9d7vQsin9pfrWdipoXvwtPgANqysVw443-HwUvLhPTuXxGsDdv0HzrvtxzVidvY_ihN45KXR4LsYQDMRNvPlCGYVJDxc3OQfV1LEgACAAQAAQAgAA; domain=.login.microsoftonline.com; expires=Sun, 12-Jan-2020 17:29:09 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: ESTSAUTH=AQABAAQAACQN9QBRU3jT6bcBQLZNUj7RkRJgm8PalY-u9YYf_I67Wxc1rqqmcQjzhap-HvzYPcg57SXUcZdCfoXzfJrakxvqnrb2ZNo9C-ZHRotgvjLc2dW6cgdeWzR3HosW2wnq46QMLuM5_9PgkVqu618TY1YjbrGHJt-DrkqYBllosEsRgIn7vtJbIDUcbIX_lY1v3x_eZDvxDC54mXpu4ahOFb2PpcMWOhQc2FvpjlBYy7n6SAAIABAACAAAAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: ESTSAUTHLIGHT=+53636a21-7ae1-44a-91b6-42bcae6e95b8; path=/; secure; SameSite=None
Set-Cookie: ch=so8u3S2kSqpfBZhYUj-R6A5pGKKa5C_O1x0BvcrUeo; domain=.login.microsoftonline.com; expires=Sun, 12-Jan-2020 17:29:09 GMT; path=/; secure; SameSite=None
Set-Cookie: ESTSSC=00; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: buid=AQABAAEAAACQNQBRU3jT6bcBQLZNUj7enEyqLfYUuELonMRUstbWJj7fo8pTcQpro4Nep0rWS5DEHS7CAeNTSacaPYMXV8117FRdTSbvvMTasm4xDvW754ejP38JWtrZYkzEgOR8GyYsywDES4s7Fh9p1Fy_m5ImVzc9weUEiDlc1yhXxSkDbDmnlv9-SjJUJmiespfBsaXtzQSrEQaPEpBT5PbY5J_oAFgzbSA0gmlO9yOWOVGOR7IsIm8L4HvgJl25zOJWRBDSHYe8uTsCyfclx9oW_iZeQ3qtgczWXpg4OSIJqB3NiAA; expires=Wed, 13-Nov-2019 17:29:09 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: SignInStateCookie=CAQABAAIAACQN9QBRU3jT6bcBQLZNUj7MpWzBN_CNnDvk5B7KLIuFNmpFhsjxyNrRZ7uaQBysuOYD52BW1DC2Rp5zZbk3RPFsZu0QKJeaCDiXBBgy7YMVKIquSviPZZfMIw1HPfm0s6Sf0lMfdgA0muXF6YFxneaZCsDq53lm6qYIlzUNhv39buD6xuCgtFl6d1OC84T65eGPSPPPBTJGO4un5QCVByDM0wbwYtXXr68c08cbT2U_ucgQ4tffRT-OUxKKlvz6nR3NcwD-Irn2Kn3Ay6_IBf7IAA; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: fpc=Ajcv9X5TAupIu9O6f-Jaazeh6BYDAQAAAJmjNtUOAAAAVCafUwEAACZpjbVDgAAAMDn2V0DAAAA46Y21Q4AAAA; expires=Wed, 13-Nov-2019 17:29:09 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: esctx=AQABAAAAAACQNQBRU3jT6bcBQLZNUj7rM2IjQVNxnrEqNXHtt2eNwsyLtgxftnSP3A1fpoRokG5weF27jPP4N4DTNZQI9-zxNnJXVD6jVR_FASWy6wvo-jYy0ddLCsC6upC3Y6n_YZSdCFixngM6Mnv3h4wAsPDbf6pzuUl7b0U8OoVe0zThFTTuQgprrs3XjHm9zEzlfAgAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
Date: Mon, 14 Oct 2019 17:29:09 GMT
Content-Length: 2650
Fail
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: -1
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
x-ms-request-id: d8d44ea8-f12b-4f77-a25e-c1802adc7300
x-ms-ests-server: 2.1.9524.8 - CHI ProdSlices
x-ms-clitelem: 1,0,0,,
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
Set-Cookie: AADSSO=; expires=Sun, 13-Oct-2019 17:30:47 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: ESTSAUTHPERSISTENT=AQABAAQAAACN9QBRU3jT6bcBQLZNUj7Ng4kTNHEzlSGq4cyWxjUgjdQKPLQpDmPkulhBzsOCuvbmS0f1XHOHjqpDjRbTlT6r7VIjA0Gmsd6jlC2vcXMeifp2g1l5iUmaRS7sRA7XYoM1lRB6BB8sR1iNU8lL5G8Pff1qnDDe0O6Y5DE3yl_V02Cl_g_fifjTWGqG32JCUoXwknLW7gJi2k6GwVEq50rLqOYcSWpC72Q4bvtV1MY7CINWCUtpfse-gGcFYHmA67eGB8a4xwzvZnVfXdBHDvGuuqtDeXp1cprMCHYX9w3PAH1Ll7wVjZj4sUm0YWzm7G0gl9ngSqObM_vigH_KiXPsVoezhlBN_Xx0pkUpgbcTg2jCZ65xmSMkG_pegf28Zbyhpde-nqLB3_apx4_CJKr4BnJfklyRWvfZay5rtPJ70fpvP0KefPCyyE-liJxa47S6omJGr3IYZsmqlXQCGnYxgV7R2JFhdatTqiMuoKaTZGi_biglipMOKq0CIwBAOhQTlnAvO3TQInL2pKu96qbGo8f4wC6qzKnkGyPRenl66HZtZ1AAtkopLm-3AazYwYe_0Ex661018bmRQ439uy1p8otKT3ZnLaF2tjbAS5oXqCixevywawSsL-PhF69GYUgACAAQABQAQAA; domain=.login.microsoftonline.com; expires=Sun, 12-Jan-2020 17:30:47 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: ESTSAUTH=AQABAAQAAACQN9QBRUjT6bcBQLZNUj7OegOzQKPWPto8WclZJmDLwYNjiEsn4OirFaDPw1GEKee53a1iFcD3LuFzjBN3PXqHmju5Wsfusj3mNowv15IWyv5qVIsSxHYlA1ESmxtT-fZsiTpW7anVdEl43kycsgEDFYjROEA_OzMt5ZdnFIH1rv5h0v4SQCrPBrofk4YRZ8PnxC-L_hvgA3jr5-YVA13aRcZdzXqAj3idML1MuwlBmXpALitYwCHaMosawMXp3mvbGSS8ly0SuW5509E9MY3Vlk1ySPPgId3z0dfK6q0hq9rdUsr7d7AZyGkmDoxGT-zjNqbBGKw9SqN0q77NYpAZZuyqnJHgxcYAilPCBi208PZ6QKuwKKGHey3J3XwtRVaJ_uBU0Ksx3uZHYWWk2plqP3Agv2EJlwqhCkoWmNMGsN84GoijysmiWizFOWaeQHcnEnBDzm9dON2eqrdTdWFUZNc7SIoLp4vhTGS7hHhSDVatAiIZX_46bVFkxGAXty6ZEOLnth2q8zQ4SbSBuccv1l2oFLKmqli2hnE5CHUuAcXazhhXSCasCFRZRrAkscqIi7mcZ2YRMiEaYZn6H092LPji0leYDNCCasKLQ-Xt1N-oJ1_aVETetoAE5_KmSoi9RV3v4rWtXOAAGvEUcfdFCAof0yRocLmjatN4HV2aa6NnDTs8hPdO61u_WsJkBjuDh8nM5B4JljqxwC4WeoQdL5G6Mq10qI6FYKqVsVwkJEyKWU01v7n_xqBFUwDoDogACAAQACwAQAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: ESTSAUTHLIGHT=+d098c80-efb8-4b0f-9ef3-eb50f58728f9; path=/; secure; SameSite=None
Set-Cookie: ch=M9_iBKa5h4GB9fhFhfjvoUmR0yjMYMpfKah1_rdomE; domain=.login.microsoftonline.com; expires=Sun, 12-Jan-2020 17:30:47 GMT; path=/; secure; SameSite=None
Set-Cookie: ESTSSC=00; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: buid=AQABAAEAAAQN9QBRU3jT6bcBQLZNUj74Z7ZEQzlF4uGSSwnUP9-Ja0eqL75M-YOBzwUWC_4Lu7A6LaJn0TBLvvMwdpkJbFLAIIGzUo8eMCLp0vXHNvrALsBRbAa1gwh7KB-M9BN-gD6nJjpKUk3tHqvFtg7c0vK6eNo4qY7r1dwIg__VOiz6aD_AN1FvNYDh-wONdgBOfLnEllftJJEZnXSwpJ6YuNGFVDZ3d4vCjAhR5Ph7IueNj783JtQEdNXVBERuIk7h6mwRqPy3lzkMhuZvtaG2359Jk93zIGAUVNb56ibCASbsCAA; expires=Wed, 13-Nov-2019 17:30:47 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: SignInStateCookie=CAQABAAIAAACQN9QBRU3jT6bcBQLZNUj7g4TAdyzUlSo2ftZ1xNmrElg_4b6mDzvn_1n-8TExkhRaPr1e8skwnPVUggSoNHxL6SQsKWCa5j_E67GlrtdtB1qlEEKpPr-fgpGAjXSYt7lC6Qxms29L-q7kBEoD--ldp0MNTtuSbqyMqSWdzrfeMskcJx-D_GwYFVT46CGOtw4ScySBxVBWJ8JGuQJcAT6i1tuHzZO2TlOLliw_H7dOuYeiKGq2CbwTcMKFPydTuBSbTlfmRdIjQ3gBHmxTQ9qIAA; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: fpc=Au_FFTZRMRlAl59trPoUI0iyECHoAgAAHynNtUOAAAAwOfZXQIAAACHpzbVDgAAAA; expires=Wed, 13-Nov-2019 17:30:47 GMT; path=/; secure; HttpOnly; SameSite=None
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
Date: Mon, 14 Oct 2019 17:30:46 GMT
Content-Length: 2522
Asp.net OpenID Connect (OIDC) middleware uses the nonce cookie to prevent security replay attack. As the error said, the application throws the above exception when it does not see the nonce cookie in the authenticated request. Cookies are domain-based so once they are set for a particular domain all subsequent requests to that domain will contain these cookies as long as they are still valid.
So, make sure the web-browser control and web browser authentication domain are the same.
The solution here is to redirect the request back to the same domain used originally after authentication. To control where Azure AD sent the authenticated request back to the application, set the OpenIdConnectAuthentications.RedirectUri property in the ConfigureAuth method below.
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
RedirectUri = "https://www.contonso.com"
});
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
}
It appears that winform's web browser control is manipulating the SameSite cookie in requests.
I had incorrectly configured the server to implement SameSite=strict, which prevented any OpenID authentication in a modern browser. Because winform's web browser control does not include this cookie I was able to successfully log in.
<rule name="Add SameSite" preCondition="No SameSite">
<match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
<action type="Rewrite" value="{R:0}; SameSite=strict" />
<conditions>
</conditions>
</rule>

C# HttpClient Post cannot get full response

i am having problem with getting full response from post request.
Specifically my problem is that in Fiddler i got full response(responses below) and in .NET i got only part of it.
I am using HttpClient and this is like my code looks like
var client = new HttpClient();
var response = client.PostAsync(url, content).Result;
in .NET i got this response (serialized to json)
{"Version":{"Major":1,"Minor":1,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1},"Content":{"Headers":[{"Key":"Content-Length","Value":["471"]},{"Key":"Expires","Value":["Thu, 19 Nov 1981 08:52:00 GMT"]},{"Key":"Content-Type","Value":["application/json; charset=UTF-8"]}]},"StatusCode":200,"ReasonPhrase":"OK","Headers":[{"Key":"X-Frame-Options","Value":["SAMEORIGIN"]},{"Key":"Pragma","Value":["no-cache"]},{"Key":"Cache-Control","Value":["no-store, must-revalidate, no-cache, post-check=0, pre-check=0"]},{"Key":"Date","Value":["Wed, 19 Apr 2017 22:13:15 GMT"]},{"Key":"Set-Cookie","Value":["SD_FRAMEWORK_SESSION=10ktfgcedl5rq427kvmo0sj7v4; path=/","user=abca7451088; expires=Sat, 20-May-2017 22:13:15 GMT; Max-Age=2678400; httponly","password=d30b0cc02736cf891cfca885ff5245bd; expires=Sat, 20-May-2017 22:13:15 GMT; Max-Age=2678400; httponly"]},{"Key":"Server","Value":["Apache"]},{"Key":"Connection","Value":["close"]}],"RequestMessage":{"Version":{"Major":1,"Minor":1,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1},"Content":{"Headers":[{"Key":"Content-Type","Value":["application/x-www-form-urlencoded"]},{"Key":"Content-Length","Value":["88"]}]},"Method":{"Method":"POST"},"RequestUri":"http://URL.COM/","Headers":[],"Properties":{}},"IsSuccessStatusCode":true}
but in Fiddler I got this response (in RAW view)
HTTP/1.1 200 OK
Date: Wed, 19 Apr 2017 22:13:15 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: SD_FRAMEWORK_SESSION=10ktfgcedl5rq427kvmo0sj7v4; 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: user=abca7451088; expires=Sat, 20-May-2017 22:13:15 GMT; Max-Age=2678400; httponly
Set-Cookie: password=d30b0cc02736cf891cfca885ff5245bd; expires=Sat, 20-May-2017 22:13:15 GMT; Max-Age=2678400; httponly
Content-Length: 471
Connection: close
Content-Type: application/json; charset=UTF-8
{"special":{"login":true,"tracking":"\n<script type=\"text\/javascript\" src=\"http:\/\/url.com\/functions.js\"><\/script>\n<script type=\"text\/javascript\">\nsetPixel ({\n'location':'SIGNUP',\n'product':'test',\n'language':'cz',\n'server-id':'lobby',\n'user-id':'340668',\n'user-email':'abca30132611#mail.col',\n'user-name':'abca7451088'\n});\n<\/script>"},"messages":{"error":[],"warning":[],"success":["V\u00edt\u00e1me V\u00e1s, abca7451088"]}}
So, how can I get that special section ("{"special":{"....") in .NET response?
Fiddler shows response content. You can get content from HttpResponseMessage using ReadAsStringAsync method of HttpContent:
var content = response.Content.ReadAsStringAsync().Result;

Invalid / expired Token - 401 - Unauthorized (Authorization Required) using Spring.Social.Twitter

I am using the Spring.Net Framework (spring.rest, spring.social.core and spring.social.twitter (2.x - oauth 1.0a) with c#.
The idea of the application will be for an event, people can link their twitter account to the event and as results are received for that person. The persons result it posted to their twitter account.
It will be made up of a website where users will register and give access. Then a console application which will process results (using the saved token set to post to registered users.
I have a web mvc application that asks a user to sign in and authorise an application so that it can post on behalf of the user. This information returned (token etc) is encrypted and kept in a db linked to the user. e.g. Our website - redirect to callback url - twitter - sign in +permission - back to callback url - store token info in db encrypted.
I then have a console application (eventually a service) which looks at results, when we have a result for a person with twitter account associated and permission given. We use that information to post to their account (their result).
The sign up process works fine, and i can post to the signed up person. saying they've registered. (website)
The console application initially worked to be able to post up results.
However, suddenly I am getting ( i think this is just a time frame (approx an hour) - works soon as a they register.)
"POST request for 'https://api.twitter.com/oauth/access_token' resulted in 401 - Unauthorized (Authorization Required)."
Linked to a user (in our system) - i am encrypting and storing verifier (from callback), secret and value. I then am using this to exchange for a access token to get secret and value to be able to post.
This is currently all a demo (going to 127.0.0.1) for a proof of concept.
So far only tried all this with the Spring.Social framework (c#)
When it works via console application -- RAW -
REQUEST
POST https://api.twitter.com/oauth/access_token HTTP/1.1
Accept: application/x-www-form-urlencoded,multipart/form-data,/
Authorization: OAuth oauth_consumer_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
, oauth_signature_method="HMAC-SHA1"
, oauth_timestamp="1417007918"
, oauth_nonce="1784014115"
, oauth_version="1.0"
, oauth_token="yyyyyyyyyyyyyyyyyyyyyyyyyyy"
, oauth_verifier="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
, oauth_signature="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
Content-Type: application/x-www-form-urlencoded
Host: api.twitter.com
Content-Length: 0
Connection: Keep-Alive
RESPONSE
HTTP/1.1 200 OK
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-length: 167
content-security-policy: default-src https:; connect-src https:; font-src https: data:; frame-src https:; img-src https: data:; media-src https:; object-src https:; script-src 'unsafe-inline' 'unsafe-eval' https:; style-src 'unsafe-inline' https:; report-uri https://twitter.com/i/csp_report?a=NVXW433SMFUWY%3D%3D%3D&ro=false;
content-type: text/html; charset=utf-8
date: Wed, 26 Nov 2014 13:18:40 UTC
etag: "fbf12c0103c8a9a4e85476ebc4a721fb"
expires: Tue, 31 Mar 1981 05:00:00 GMT
last-modified: Wed, 26 Nov 2014 13:18:39 GMT
pragma: no-cache
server: tsa_b
set-cookie: twittersess=BAh7BzoPY3JlYXRlZF9hdGwrCAnzQOxJAToHaWQiJTZjODM4ZWMwZDg4ZjY0%250ANGFjYWE0N2M1YWU0MmMzNmZl--af2ffe955256e30da84bc52b585d7c30b6926284; domain=.twitter.com; path=/; secure; HttpOnly
set-cookie: guest_id=v1%3A141700791973784560; Domain=.twitter.com; Path=/; Expires=Fri, 25-Nov-2016 13:18:40 UTC
status: 200 OK
strict-transport-security: max-age=631138519
vary: Accept-Encoding
x-connection-hash: bd73d7f87abb9c16caef67f675d8641b
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-mid: 4e5118e4376219e001674f1292c123965885210f
x-runtime: 0.10480
x-transaction: d24c3b12ea39be37
x-ua-compatible: IE=edge,chrome=1
x-xss-protection: 1; mode=block
oauth_token=xxxxx-xxxxxxxxxxxxxxxxxxxxxx&oauth_token_secret=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&user_id=2xxxxxxxxxxxxxx&screen_name=naxxxxxx
After about an hour(couple of hours in this instance) same code will fail.... with HTTP/1.1 401 Authorization Required - Invalid / expired Token.
REQUEST
POST https://api.twitter.com/oauth/access_token HTTP/1.1
Accept: application/x-www-form-urlencoded,multipart/form-data,*/*
Authorization: OAuth oauth_consumer_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
, oauth_signature_method="HMAC-SHA1"
, oauth_timestamp="1417018992"
, oauth_nonce="2294192392"
, oauth_version="1.0"
, oauth_token="yyyyyyyyyyyyyyyyyyyyyyyyyyy"
, oauth_verifier="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
, oauth_signature="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
Content-Type: application/x-www-form-urlencoded
Host: api.twitter.com
Content-Length: 0
Connection: Keep-Alive
RESPONSE
HTTP/1.1 401 Authorization Required
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-length: 136
content-security-policy: default-src https:; connect-src https:; font-src https: data:; frame-src https:; img-src https: data:; media-src https:; object-src https:; script-src 'unsafe-inline' 'unsafe-eval' https:; style-src 'unsafe-inline' https:; report-uri https://twitter.com/i/csp_report?a=NVXW433SMFUWY%3D%3D%3D&ro=false;
content-type: text/html; charset=utf-8
date: Wed, 26 Nov 2014 16:23:13 UTC
expires: Tue, 31 Mar 1981 05:00:00 GMT
last-modified: Wed, 26 Nov 2014 16:23:13 GMT
pragma: no-cache
server: tsa_b
set-cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCEzs6exJAToHaWQiJWI5MDgzMzk0Y2FhMGY2%250AMGNlNmEyYzQzZjk5OGEyNjAyIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--86562a75e3ddabab3c688e726e6c42fe37a067ea; domain=.twitter.com; path=/; secure; HttpOnly
set-cookie: guest_id=v1%3A141701899357688419; Domain=.twitter.com; Path=/; Expires=Fri, 25-Nov-2016 16:23:13 UTC
status: 401 Unauthorized
strict-transport-security: max-age=631138519
vary: Accept-Encoding
www-authenticate: OAuth realm="https://api.twitter.com"
x-connection-hash: 24d849ec3bead25133b581794d34c74f
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-mid: aed281dc4b2e3fb483737ccd772ce1d8d3f6064d
x-transaction: d41ff14981c7a0ec
x-ua-compatible: IE=edge,chrome=1
x-xss-protection: 1; mode=block
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Invalid / expired Token</error>
<request>/oauth/access_token</request>
</hash>
Can anyone help or advice on what I should be persisting to be able to post on behalf of a user - once they've given us permission from a service or console application.
Thanks in advance.
I managed to solve issue. I removed Spring.Social from equation and wrote some quick code to talk to Twitter API without a framework, this gave me a better understanding of what the steps and process were.
Using this I then re-added the framework and I think I use it correctly now. As it all works.
My issue was that once I got my request token+verifier - supplying callback, consumer etc. I then used that to get an access token to perform posts etc.
However, every time I attempted to post I tried to exchange request token value + secret and verifier to get the access token. This eventually fails.
I changed code to save returned access token and just use that directly, works fine now.

Yammer API alternates responses 302 and 404

I'm programmatically trusting my yammer app through .NET. While debugging the POST request to trust an app, the responses can seemingly arbitrarily render either a 302 or a 404 as the response tries to redirect to a SharePoint MySite host.
If I during the same debug session loop my requests, I get the same type of response. I have to restart debugging to have a chance at a different response. I have tried setting minute long sleeps to ensure that time has nothing to do with which type of response I get. Same rule seem to apply: One debug session, one response type.
My question is now: What do I need to do to avoid these 404's?
Here's the fiddler responses:
THE 302 RESPONSE:
POST https://www.yammer.com/MYNETWORK/oauth2/decision?client_id=MYAPPCODE&redirect_uri=http%3a%2f%2fmy.devmachine.contoso.com&response_type=code HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: www.yammer.com
Cookie: yamtrak_id=[GUID]; _workfeed_session_id=[ID] Content-Length: 90
Expect: 100-continue
utf8=%E2%9C%93&authenticity_token=[TOKEN]=&allow=Allow
HTTP/1.1 302 Found
Server: nginx
Date: Mon, 29 Sep 2014 13:21:51 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: close
Status: 302 Found
Location: http://my.devmachine.contoso.com?code=[CODE] X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: yamtrak_id=[ID]; path=/; expires=Tue, 29-Sep-2015 13:21:51 GMT; secure; HttpOnly
Set-Cookie: auth_token=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT; secure
Set-Cookie: auth_token_sso=; domain=yammer.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT; secure
X-Date: 1411996911966
X-Runtime: 0.073263
7e
<html><body>You are being redirected.</body></html>
0
THE 404 RESPONSE:
POST https://www.yammer.com/MYNETWORK/oauth2/decision?client_id=MYAPPCODE&redirect_uri=http%3a%2f%2fmy.devmachine.contoso.com&response_type=code HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: www.yammer.com
Cookie: yamtrak_id=[GUID]; _workfeed_session_id=[ID]
Content-Length: 90
Expect: 100-continue
utf8=%E2%9C%93&authenticity_token=[TOKEN]=&allow=Allow
HTTP/1.1 404 Not Found
Server: nginx
Date: Mon, 29 Sep 2014 13:26:03 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Status: 404 Not Found
Cache-Control: no-cache
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
X-UA-Compatible: IE=Edge,chrome=1
X-Date: 1411997163223
X-Runtime: 0.068703
a45
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=8,chrome=1" />
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>The page you were looking for doesn't exist (404)</title>
<link href="/stylesheets/yamkit/yam.css" media="screen, projection" rel="stylesheet" type="text/css" />
<style type="text/css">
body {
...
<div id="parallax-static">
<div id="parallax-static-text">
<h1>Oops!</h2>
<h2>The page you were looking for could not be found.</h2>
Let's go back to your happy place.
</div>
</div>
...
</body>
</html>
0
I'm aware of the other yammer threads in this forum, and I'm using the new login_csrf_token cookie to authenticate, so that shouldn't be the issue.
Thanks for Reading! I'm grateful for any suggestion on how to solve this.
EDIT: I've tried setting another site (google) as my redirect url, but the alternating behaviour persists.
Found it: Turns out that sometimes the authenticity token contains plus characters (+) which needs to be URL encoded. The tokens can also contain front slashes (/) but they don't trip up the succeeding call to /session or /oauth2/decision, only plus does.

Cannot Return Custom HTTP Error Details Remotely

This is a strange one. I'm running MVC 3 and have a custom action result that wraps exceptions and returns a message along with the standard HTTP error.
public class ExceptionResult : ActionResult
{
private readonly Exception _exception;
public ExceptionResult(Exception exception)
{
_exception = exception;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ClearHeaders();
response.Cache.SetNoStore();
response.ContentType = ContentType.Json;
var baseEx = _exception as BaseException ?? new ServerException(_exception);
var result = baseEx.GetResult();
var json = result.ToJSON();
response.Write(json);
response.StatusCode = (int)result.Status.Code;
}
}
When I run this locally I get exactly what I expect:
HTTP/1.1 400 Bad Request
Cache-Control: no-store
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Date: Thu, 01 Dec 2011 19:00:03 GMT
Content-Length: 81
{"error":"invalid_request","error_description":"Parameter grant_type is missing"}
But when I try to connect from a different machine I get the standard IIS error message instead:
HTTP/1.1 400 Bad Request
Cache-Control: no-store
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Date: Thu, 01 Dec 2011 19:02:33 GMT
Content-Length: 11
Bad Request
UPDATE
There must be some http module somewhere in the IIS pipeline that is swallowing the response and rewriting the content. I wrote a module to log the request and response and it's returning exactly what I expect however what actually makes it to the browser is wrong.
2011-12-02 15:39:00,518 - ======== Request ========
2011-12-02 15:39:00,518 - GET /oauth/2/token HTTP/1.1
2011-12-02 15:39:00,519 - Cache-Control: max-age=0
2011-12-02 15:39:00,519 - Connection: keep-alive
2011-12-02 15:39:00,519 - Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2011-12-02 15:39:00,519 - Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
2011-12-02 15:39:00,519 - Accept-Encoding: gzip,deflate,sdch
2011-12-02 15:39:00,519 - Accept-Language: en-US,en;q=0.8
2011-12-02 15:39:00,519 - Host: micah-pc:8095
2011-12-02 15:39:00,519 - User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2
2011-12-02 15:39:00,519 - =========================
2011-12-02 15:39:00,519 - OAuth exception occurred.
BoomTown.OAuth.OAuthException: Parameter grant_type is missing
at BoomTown.OAuth.Request.TokenRequest.GetRequestValidator() in C:\code\BoomTown\Api\BoomTown.OAuth\Request\TokenRequest.cs:line 19
at BoomTown.OAuth.Request.OAuthRequestBase.Validate() in C:\code\BoomTown\Api\BoomTown.OAuth\Request\OAuthRequestBase.cs:line 33
at BoomTown.OAuth.Request.OAuthRequestBase..ctor(HttpRequestBase request, IOAuthServiceLocator serviceLocator) in C:\code\BoomTown\Api\BoomTown.OAuth\Request\OAuthRequestBase.cs:line 28
at BoomTown.OAuth.Request.TokenRequest..ctor(HttpRequestBase request, IOAuthServiceLocator serviceLocator) in C:\code\BoomTown\Api\BoomTown.OAuth\Request\TokenRequest.cs:line 13
at BoomTown.Api.Web.Controllers.OAuth.V2.OAuthController.Token() in C:\code\BoomTown\Api\BoomTown.Api.Web\Controllers\OAuth\V2\OAuthController.cs:line 26
2011-12-02 15:39:00,520 - ======= Response =======
2011-12-02 15:39:00,520 - HTTP/1.1 400 Bad Request
2011-12-02 15:39:00,520 - Cache-Control: no-store
2011-12-02 15:39:00,520 - X-AspNet-Version: 4.0.30319
2011-12-02 15:39:00,520 - Content-Type: application/json; charset=utf-8
2011-12-02 15:39:00,520 - {"error":"invalid_request","error_description":"Parameter grant_type is missing"}
SOLUTION
Thanks to a little sleuthing I was able to figure it out. I setup IIS tracing which confirmed my suspicions that it was related to the customerrormodule which was intercepting my requests and overwriting my error messages. I kept monkeying with the
<system.web>
<customErrors />
<system.web>
settings but to no avail. I was on the right track, but since it's IIS 7 that I'm running I needed to change the correct web.config section like this:
<system.webServer>
<httpErrors errorMode="Detailed" />
</system.webServer>
Now all my custom JSON messages come through perfectly. Big thanks to Jason Finneyfrock for the tag team on this one.
In your web.config, do you have httpErrors defined to only be DetailedLocalOnly? I'm not sure whether or not the content would be removed in this situation.
http://www.iis.net/ConfigReference/system.webServer/httpErrors
I came across this, not sure if it will help:
context.HttpContext.Response.TrySkipIisCustomErrors = true;

Categories

Resources