Change browser headers when redirecting - http

I have the following situation:
The browser does a POST with a Json payload to my server endpoint
My server processes the data and then issues a redirect to a new location
The browser does the redirect, but it does it with the same headers as the original post which mean it arrives at my endpint such that my endpoint
thinks it is a json request.
-> I want the redirect to arrive at my server as a standard text/html request.
Is it possible to control the headers that the redirect uses so that the Get request arrives with text/html Accept headers?
Here are some snippets from fiddler to highlight what I am talking about:
Initial POST, json payload:
POST /App/Client/Index HTTP/1.1
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest
The response:
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
The subsequest GET request from the Redirect:
GET /App/Client/SingleEntity?entityId=f859a6ca-dbcf-49cf-8de0-3888b7011815 HTTP/1.1
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest

I had a similar requirement. My solution was to not send a redirect, but a "200 OK" with the following JSON:
{"url": "http://example.com/redirect/to/some/resource"}
The client used the URL and redirected via Javascript, i.e. location.href = data.url. It might not be the answer you're looking for but it solves your problem...
See also: How to manage a redirect request after a jQuery Ajax call

Related

CORS Google Cloud - Authorization header in the OPTIONS via Axios

I have a CORS-enabled Spring Boot API that runs on Google Cloud Run and a Vue.js front end that runs on Firebase and uses Axios to make the calls to the back end.
The Problem is that when the front end wants to access the back end (Browser --> Google Clud), it fails with:
Access to XMLHttpRequest at 'https://<backend>' from origin 'https://<frontend>' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If I access from LOCAL front end (also Browser) to a LOCAL back end, it works: The error above is not shown in the Browser console and I get the data).
If I make the OPTIONS or GET call from Postman to the Google Cloud back end, it works.
I noticed, that with Postman I need to include the Authorization header in the OPTIONS request to send the Bearer token to Google to make it work. The Browser does not send any Authorization header in the OPTIONS call, even if I add withCredentials: true to the Axios config like this:
const response = await axios({
method: 'post',
withCredentials: true,
url: 'https://<backend>',
headers: {
'Authorization': 'Bearer ' + gCloudToken
},
data: {
// data...
}
});
Isn't that a security problem, to send the token in the header? I mean, everyone can see the headers and then fake a call to the server.
Can anybody show how to send the Authorization header in the OPTIONS call via Axios or tell how to correctly handle this problem?
UPDATE 1:
The request from the browser looks like this:
OPTIONS /path/to/api HTTP/2
Host: <backend>-ew.a.run.app
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Referer: https://frontend.web.app/
Origin: https://frontend.web.app
Connection: keep-alive
And this is the response:
HTTP/2 403 Forbidden
date: Tue, 07 Jul 2020 23:57:27 GMT
content-type: text/html; charset=UTF-8
server: Google Frontend
content-length: 320
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
X-Firefox-Spdy: h2
As you can see, no CORS headers (like e.g. access-control-allow-origin) are present.
The cause of this issue is that by not allowing unauthenticated calls the CORS preflight are always rejected with a 403 error message.
There is already a feature request for Cloud Run in orther to support CORS and authentication with Cloudrun.
The Workaround I would see so far is to allow unauthenticated calls on the CloudRun and implement the authentication on your code, However this can have security disadvantages.

AngularJS CORS issues data won't load

I am getting the following error message on my angular/asp.net web api project.
XMLHttpRequest cannot load http://localhost:7291/api/products. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7305' is therefore not allowed access. The response had HTTP status code 500.
I know it has something to do with CORS not being implemented correctly, but I'm not sure what I'm doing wrong. I'm following a tutorial and as far as I can tell I've got everything right?
Here's the info from the network tab in chrome debug.
Remote Address:[::1]:7291
Request URL:http://localhost:7291/api/products
Request Method:GET
Status Code:500 Internal Server Error
Response Headers
(8)
Request Headers
view source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:7291
Origin:http://localhost:7305
Referer:http://localhost:7305/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Here is where I map the API url.
(function () {
"use strict";
angular
.module("common.services", ["ngResource"])
.constant("appSettings",
{
serverPath: "http://localhost:7291/"
})
}());
And this is how I'm setting up the EnableCOrsAttribute:
[EnableCorsAttribute("http://localhost:7305", "*", "*")]
Can anyone see what I'm doing wrong? If more code is needed please let me know. Thanks.
First Step, use a tool like Postman or Fiddler to verify your service endpoint first to ensure functionality.
It looks as if this is not a CORS issue at all, due to the 500 response:
Status Code:500 Internal Server Error
A CORS issue on a normal success response is usually manifested as a status 0 or -1 in the client, but what you are experiencing is an error on the server side. I have seen this in my own code and suspect that your implementation on the server side is only injecting the CORS headers at the end of processing the request and as the processing abnormally aborted the CORS headers didn't make it in there.
Once you have confirmed functionality do an OPTIONS request on your endpoint to verify CORS:
OPTIONS / HTTP/1.1
Host: localhost:7291
Cache-Control: no-cache
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Then inspect the headers of the response, if your CORS is enabled correctly on the server you should see Access-Control-Allow headers similar to this:
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, ETAG
Access-Control-Allow-Origin: http://localhost:7305

getting oauth_problem=signature_invalid when exchanging LinkedIn JSAPI token for OAuth token

I am following linked in documentation to exchange a JSAPI token for a OAuth 1.0a token. (https://developer.linkedin.com/documents/exchange-jsapi-tokens-rest-api-oauth-tokens)
I got the following error during the exchange:
oauth_problem=signature_invalid&oauth_problem_advice=com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException%20while%20obtaining%20request%20token%20for%20%3APOST%26https%253A%252F%252Fapi.linkedin.com%252Fuas%252Foauth%252FaccessToken%26oauth_consumer_key%253D751oglji2r3e9e%2526oauth_nonce%253D1422656976%2526oauth_signature_method%253DHMAC-SHA1%2526oauth_timestamp%253D1422656976654%2526oauth_version%253D1.0%2526xoauth_oauth2_access_token%253DzdLOTq4fVfiSBS4WP_FkEgL942vbUkpsH4gH%0ACONN%3AO%7C4245561%7C3241891%7C7315878%7C4307091%7C%2A02%3A1422656976%3AgwtcYNp1ZiULkjvCXvnbOWM2fps%253D
I used the the LinkedIn OAuth test console to test my signature algorithm
(https://developer.linkedin.com/oauth-test-console)
and I confirmed that I am constructing the same base_string and got the same signature as the test-console.
However I am still getting the signature_invalid error which suggest that I might be constructing the HTTP POST request incorrectly.
This is what my request looks like:
POST /uas/oauth/accessToken HTTP/1.1
Authorization: OAuth oauth_consumer_key="751oglji2r3e9e", oauth_nonce="1422654439", oauth_signature="vif9BS8MFNdjTWCagrs%252Fn8gNa1Y%253D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1422654439035", oauth_version="1.0"
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.7.0_71
Host: api.linkedin.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, /; q=.2
Connection: close
Content-Length: 63
xoauth_oauth2_access_token=AykDWuciDtpUQ_2tY4y3sKOOqOD6JXUSwuZR
I url encoded my signature because this is what some of the other post suggest. Is this the right way?
The error message from LinkedIn does not make it clear as to why the signature is invalid.
Re-examining the signature in the Authorization header, it appear that I made the mistake of URL encoding the signature twice when putting it in the Authorization header.
Once I fix this I was able to obtain the access token.

Why .Net WebApi don't detect the request contentType automatically and do auto-binding?

Why .Net WebApi don't detect the request contentType automatically and do auto-binding?
If I make a request without informing the contentType a HTTP 500 error occour:
No MediaTypeFormatter is available to read an object of type 'ExampleObject' from content with media type ''undefined''.
why not try to detect the incoming data and bind automatically?
Another case:
This request with Content-Type: application/x-www-form-urlencoded send a JSON:
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: localhost:10329
Content-Length: 42
Request Body:
{"Name":"qq","Email":"ww","Message":"ee"}:
My Action don't detect the JSON request data automatically in object param:
public void Create(ExampleObject example) //example is null
{
{
Instead of letting the object null why they do not try to solve it?
Then, for the binding occurs I need to send with Content-Type: application/json.
It would be best if .Net WebAPI detects the type of request data and do a auto-binding? Why not in this way?
application/x-www-form-urlencoded means you will be sending data in the x-www-form-urlencoded standard. Sending data in another standard will not work.
Sounds like what you want to do is accept multiple formats from the server.
the way http works is that the client makes a request to the server for a resource and tells the server what content types it understands. This means that the client doesnt get a response it isnt able to decode, and the server knows which responses are more appropriate on the client. For example if you are a web-browser the most appropriate content type is text/html but if you get XML you can probably do something with that too. So you would make a request with the following:
accept: text/html, application/xml
this says you prefer html but also understand XML
In your example if your client wants application/x-www-form-urlencoded but can also deal with JSON then you should do the following when making a request
accept: application/x-www-form-urlencoded, application/json
For more details see the HTTP Spec on accept headers here http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
You may also want to create a new media type formatter so your server knows how to give clients application/x-www-form-urlencoded, take a look at this blog post for more info on how to do this http://www.strathweb.com/2012/04/rss-atom-mediatypeformatter-for-asp-net-webapi/

uploadify: HTTP request sent to backend

I've a custom webserver which parses HTTP requests including multipart-form data.
In case of following, things are good:
<FORM method = "POST" action = "#" enctype multipart form-data multiple>
<INPUT type = "file"/>
<INPUT type = "submit"/>
</FORM>
The above HTML sends request which look like:
POST / HTTP/1.1
Host: 192.168.1.2:8888
User-Agent: Shockwave Flash
Connection: Keep-Alive
Cache-Control: no-cache
Accept: text/*
Content-Length: 884
Content-Type: multipart/form-data; boundary=----------------------------1193f8fd031d
img 1
----------------------------1193f8fd031d
img 2
----------------------------1193f8fd031d--
In case I use uploadify as per its docs, I donot get similar HTTP request at the backend.
How can I view HTTP request which uploadify sends?
On the server you can install Wireshark or try using fiddler on the client-side to view the HTTP communication.

Resources