WKWebView can't carry cookie for 302 redirect - redirect

I set cookie in request header before I call loadRequest() function to load a page. I also use document.cookie() to set cookie by WKUserScript according to [WKWebView Cookies. However, I find that if a 302 redirection occurs, request may fail for loss of cookie. For example, the request of http://A redirect to http://B, I could set cookie for request of http://A by operating request head and using WKUserScript, but these two ways can not set cookie for request of http://B, so the 302 request of http://B may fail. This situation occurs in ios8 more frequently than ios9. Does anybody have a workaround?

Note sure, but probably the first response may contain "Set-Cookie" header. Hence, you have to use the provided cookie in the second request. May be it's missing.

workaround for set cookies in iOS please check my answer. You must set cookies both in request and wkuserscript same time. otherwise it fail one time and sucess in 2nd run,
Can I set the cookies to be used by a WKWebView?

Related

Webextension: Set response headers for web_accessible_resources

To provide some custom caching via a webextension, I use web_accessible_resources and redirect accesses towards them in a background script – see my previous question for details.
While that works content wise, I cannot find a way to change the response headers of the cached content, for example the Last-Modified header. So when I cache content that the original website does some consistence checks on, this will fail.
I tried to intercept the redirected response with an onHeadersReceived handler, but this never triggers as “Only requests made using HTTP or HTTPS will trigger events” and my redirect uses the moz-extension:// protocol.
How does one set response headers when serving web_accessible_resources?
Is it possible at all?

can I pass headers to redirected location after redirection?

here's response header of my redirection endpoint with status code 302.
"Location": "http://<target-domain>",
"Set-Cookie": "username=user1;"
I can see it redirects correctly to 302. but the cookie does not get set on the <target-domain>
Looks like the header "Set-Cookie": "username=user1;" does not get passed to the <target-domain> on redirection.
I see 2 network activities in my development tool,
redirection endpoint responds with status code 302. I see Location and Set-Cookie in the response header.
target domain responds with status code 200. I don't see Location and Set-Cookie anymore.
Is there a way to set the cookies on the <target-domain>?
You can't set cookies on a domain other than the one you're on, so basically no. The only exception to this is you can set cookies on example.com if your current domain is something like subdomain.example.com, where you can attach the cookies to a shorter form of your domain, but it must be the same base domain.
If you need the other site to set a cookie with a value it does not know, you'll have to pass that value through somehow. Using a redirect with a query string leaves it open to tampering by the user unless you cryptographically sign it (annoying) or ship over a token that can be used to retrieve the raw value. You may need a short-term store for this, like Redis, Memcached, or even a database row you can purge later.
If it were possible to set cookies on any domain at all there'd be utter chaos. These things are heavily restricted for a reason.

HTTP Redirect Status Code

I have an ASP.NET website. A user can access the URL /partners/{partner-id} in my app. When that url is invoked, I do two things:
1) I want to log the partner ID and user that requested it and
2) Redirect the url to the partner's website.
My question is, which HTTP Status Code should I use? I was using 301. However, that introduced a problem where my logging code was getting skipped. I suspect its because a 301 represents a permanent redirect. However, I basically want to remain the middle man so that I properly log the details.
What HTTP status code should I use?
Thanks!
Taking a look here:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
you should use the 302 status code. Two useful points about the 302 redirect:
Since the redirection might be altered on occasion, the client SHOULD
continue to use the Request-URI for future requests
This says by inferring that the redirect may be temporary, clients should always check the initial URI instead of going to the redirect URI as a default behavior, meaning they will pass through your logging system each time rather than going directly to the redirected URI on subsequent requests. The 302 response also states:
This response is only cacheable if indicated by a Cache-Control or
Expires header field.
By default, the 301 redirect is cacheable unless you explicitly specify, but the 302 is not cacheable unless explicitly specified.
However, it's probably a good idea to explicitly add in 'do not cache' headers to the redirect to let the client know that it should not be cached just in case you have a client that doesn't follow the default spec behavior. There are a number of other answers in stackoverflow regarding this, here's a decent one:
How to control web page caching, across all browsers?

How to capture redirect response header

I am trying to record a simple login and logout flow for a .Net application. After I submit the login credentials the welcome page's URL has a large alpha numeric number. This number is required to continue to the next steps.
On Fiddler I have noticed that the login credential submission request results in a 302 response and this response contain an a=129characterstring that i need in my subsequent requests.
On JMeter I have added a recording controller and on the HTTP(S) Test Script Recorder I have Follow Redirects and Use KeepAlive checked (See below screenshot)
I have also recorded with Follow Redirects unchecked and different options for Grouping and HTTP Sampler Settings.
But with none of them I am able to record/capture the 302 response that i see on fiddler. Instead the login credential submission request always returns a 200 response, even if the login fails.
It is not as if that JMeter is not recording redirect requests, further down the scenario flow I have another redirect request which is captured.
I can't be the only one who is/has faced this problem. Does anyone have any suggestions on what I should be doing differently to get the 302 response?
To do this:
Record with default options, the redirect Http Request triggered by 302 will be disabled by default.
Then you will need after this to uncheck "Follow Redirect" in the first one, and add a Regular Expression Post Processor to extract the data you want.
Then enable the commented second request and inject the extracted variable.

Handling HTTP 302 error and redirecting in Backbone.JS "sync" method

I've got a secured Backbone.js app (that uses Spring security atm.), so a logged-in user must have a valid session-cookie (JSESSIONID). Now, if this session is invalidated (deleted, expired, whatever) and the user attempts to make a request, Spring security will return a 302 Error as an attempt to redirect the user to a login-form.
As is explained in this answer, this 302 response gets handled by the browser (it doesn't reach my app) so what is returned to my app is a 200 OK response with contenttype="text/html" (containing the login form).
Thats an issue, because when my Backbone model attempts to do a sync to a url, it expects JSON. If this sync happens without a valid session, the 200 "text/html" response is returned when "application/json" is expected, giving me a JSON parse error in jQuery.extend.parseJSON.
With great help from this question/answer, I've overridden the Backbone.sync method in order to use my own error handling. However, since the 302 never reaches my error handler I cannot override the redirect myself.
My situation is very similar to this question, however a final solution to the problem was never posted. Could someone please help me figure out the ideal way to ensure a redirect to the login page happens?
Instead of returning the login page with HTTP 200 OK, you should configure Spring Security to return HTTP 401 Unauthorized for unauthenticated AJAX requests. You can detect an AJAX request (as opposed to a normal page request) by checking for the X-Requested-With: XMLHttpRequest request header.
You can use the global $.ajaxError handler to check for 401 errors and redirect to the login page there.
This is how we've implemented it and it works nicely. I'm not a Spring guy, though, so I can't really help with the Spring Security configuration.
EDIT. Instead of custom coockie it will be better to use solution provided by #fencliff.
I think you can use some other field of XHR to detect this situation. A special coockie may do the trick.
You can define your own authentication failure handler from Spring Security side. At the moment when redirect to login page occurs you will be able to add some coockie to HttpServletResponse. Your custom Backbone.sync method will check this cookie. If it is present, it will launch your custom handler for this case (do not forget remove the coockie at the same time).
<sec:http ... >
<sec:form-login login-page='/login.html' authentication-failure-handler-ref="customAuthenticationFailureHandler" />
</sec:http>
<bean id="customAuthenticationFailureHandler" class="com.domain.CustomAuthenticationFailureHandler" />
CustomAuthenticationFailureHandler must implement org.springframework.security.web.authentication.AuthenticationFailureHandler interface. You can add your coockie and then call default SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure(...) implementation.