in my iPhone/iPad-app I've got to deal with a server which determines sessions (not only, but also) according to the IP-address. The problem now is that with some providers, the phone's IP address changes after a few seconds and therefore the server can't recognize the session any more.
Is there any way to handle this on the client and "help" the server to stay unchanged without configuration changes? Or is it only possible serverside?
I'm not using a library (ASIHTTP-request, e.g.), but only NSURLConnection.
Nope, nothing you can do client side. You will have to configure the server to accept session ID only.
Related
I have an iOS app where the user can makes HTTP requests from their phones and the HTTP returns information based on the zip code that the user provides through the phone.
My issue is that anyone can type the URL and the server would respond with the information that corresponds to the zip code they input e.g. http://example.com/zip-code/78515.
My questions is, can I limit the server to only respond to requests made from my iOS app without the user having to create a user and password? In other words, if someone types http://example.com/zip-code/78515 directly in a browser I want the server to ignore the request but if the request comes from my iOS app I want the server to respond accordingly.
For the HTTP request I'm using Laravel.
Here is my Laravel code.
Route:
Route::get('zip-code/{zipCode}', 'AppsAPIController#information');
Controller:
class AppsAPIController extends Controller
{
public function information($zipCode)
{
$info = CityInfo::where('ZipCode', $zipCode)->get();
return ($info);
}
}
Request:
http://example.com/zip-code/78515
Again, the question is, how can I limit the server to only respond to requests made from my iOS app without the user having to create a username and password?
This package seems to do that
https://github.com/spinen/laravel-browser-filter
Basically, you are adding a middleware that reads the user agent out of the request, and denies the rest.
There is no foolproof way to respond only to requests made by your app.
User agent sniffing, navigator feature detection, and like measures may deter most basic attempts to load information from that url (like search engine bots), but anyone with a little time can learn to replicate the HTTP requests made by your app, defeating those measures.
Even requiring a login will not prevent external request (they can send requests matching your login workflow to obtain a valid token, then request the restricted url with it).
(via the comments) I just don’t want to overload the server with unnecessary requests.
In that case, there's a much better solution. Laravel ships with a throttle middleware, which you can use to limit the number of requests per minute per IP (or per logged-in user, if they're authenticated).
Just add throttle:60,1 to your route's middleware and it'll max out at 60 requests per minute for a particular IP address. Set it to something relatively high (so normal use doesn't hit it), but it'll prevent millions of requests from the same IP from using up too many resources.
I'm trying to understand the functionalities of Keycloak and trying to find a way to monitor request flows (like in Wireshark) in a local environment (localhost). What tool could I use for this purpose in a Windows environment? I've got an Angular app that is integrated with Keycloak, and it works. When I request localhost:4200, the browser takes me to Keycloak login screen.
To view logs, I changed the log level in the Keycloak server at ..\keycloak-4.8.3.Final\standalone\configuration from INFO to ALL. It did expand the log entries that showed in the console but it didn't show any logs when my angular application redirects to Keycloak and when I enter user credentials in Keycloak login screen.
I would like to see the request flow from browser to Keycloak and all the auth requests and so on. Is there a tool that I could use for this purpose?
Configure the events part of the server the way you prefer. They are stored in the DB.
Keycloak provides a rich set of auditing capabilities. Every single
login action can be recorded and stored in the database and reviewed
in the Admin Console. All admin actions can also be recorded and
reviewed. There is also a Listener SPI with which plugins can listen
for these events and perform some action. Built-in listeners include a
simple log file and the ability to send an email if an event occurs.
Still I don't know if this covers the specific case of your application redirecting to the KC login screen. If not, you might need to log this in your application, but it might be a little bit tricky if you use the Angular adapter, as it gets executed in client side (you would need to do POST to some server that you own to get it logged, or directly switch to any server side based KC adapter).
another way to get the event is from the
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl("localhost")
.realm("myRealm")
.grantType(OAuth2Constants.PASSWORD)
.clientId("myclient")
.clientSecret("xxxx-xxxxx-xxxx-xxx")
.username("foo")//the admin user
.password("password")
.build();
List<EventRepresentation> events = keycloak.realm("myRealm").getEvents();
then you choose the type of event you want to target
I have an application that rotates an auth token cookie values regularly.
Each time the server rotates the token, it will not mark it as "good" until it sees the client has the token (cause the client includes it in the request headers for a resource).
I have a very specific situation ONLY on iOS (10.3) where sporadically it will send a very old cookie when network conditions change (eg: get off the subway). When this condition hits it "forgets" about the most recent cookie value and "starts living in the past" and sends and old value.
** Security note: IP addresses are publicly allocated t-mobile in NYC and token has long been deleted from our DB
Is this a known issue?
Are there any workarounds for cookie handling that is more robust on iOS? localstorage is not ideal cause these cookies are http only.
To clarify ... this is the flow:
Client (iOS Safari) has a cookie called _t with the value old
Client (iOS Safari) makes a request to the server
We issue Set-Cookie and set _t cookie to a new value new (http only, secure cookie)
Client makes another request with the new cookie value new. We flag that the cookie value is good and client has it.
Time passes
Client makes a request with the _t cookie with the value old
Here is my theory of what happened:
From the cookies lifecycle, whenever user authentication state change (login user -> logout user || logout user -> login user), the old cookie would be invalidated and replaced with a new cookie.
But why that happened in the subway and not other places?
1. These days most subways provide free unsecured WiFi to supplement the bad wireless network connectivity while underground.
2. There were some reports on network connectivity issue in 10.3, and
this one in particular is interesting, as the issue was location dependent.
3. I think the combination of (1) and (2) above was causing the app to reauthenticate to the server. Maybe you could pull the logs to check if that is indeed the case?
Possible workaround?
Maybe none. We can't prevent iPhone user from doing iOS upgrade. And most already did.
Also, the security repercussion of not changing cookies after reauthentication is worse.
Update based on the comment as of 05/31/2017:
Given the details as in the comment. We could have better explanation.
In cookie life cycle, when user logout, server-side-invalidation should take place.
The work flow:
1. When the user logout, the authenticated sessionID is deleted from the browser.
2. But that's not enough. The server needs to invalidate that sessionID too. Else there could be security repercussion.
3. It could be that in your case the server didn't invalidate. Thus it still expecting a SessionID which has been deleted from the browser.
This is just one possible explanation. To be exact, more details log file analysis and more experiment would be required.
For example, during that period, at the server log were there any reauthentication took place? Could we test in a controlled environment, if the server-side-invalidation has been implemented properly?
My experience
I also use authentication via IDs that change with each request and are stored in cookies.
I can confirm this behavior and it is still present in iOS 11 (and iOS 11.1 beta 3). In my log files, I can see that sometimes old cookies are randomly stored in Safari. This happens in a standalone webapp when it is closed and reopened.
My Fallback method
I built a fallback method over localStorage. A request with an old cookie will normally mark all data in my database as invalid. If the user agent points to a device with iOS, I do not mark the data as invalid and give the client a second attempt to authenticate itself.
On the client side I check the localStorage and create new cookies with this data. Subsequently, a new authentication takes place. The localStorage is rewritten like the cookies with each request. If authentication fails again, I mark the data as invalid.
Safari View Controller no longer shares cookies with Safari in iOS 11 and up, this change resolved the cookie store corruption issues that plagued iOS. We have not experienced this issue ever since iOS 11 was released.
Maybe that's caused by automatic retries?
Those posts mention that can happen under bad network conditions (like you said, subway):
https://medium.com/#fagnerbrack/the-day-a-bug-was-fixed-only-because-the-ceo-called-in-f653a34079eb
https://blogs.oracle.com/ravello/beware-http-requests-automatic-retries
SQLite database, if you're willing to sacrifice a little security.
I have a website that users can log into to see their account info.
I would like to build functionality into my iOS app that allows them to log in and see their info in the app. The usernames and passwords are stored in a SQL database.
How can I authenticate the username and password the user types into the app with the database?
If you have better atuthentication system in your web..
then i would prefer you to use the WEBVIEW for your login page. and continues the other using the normal app flow.
there are lot of tutorials for creating username and password login Function in IOS. i dont know whther you are basic or new progrmmer. But try this you may get some idea.
http://www.youtube.com/watch?v=HrZR2SyeoSk.
You can go with JSON serialisation, if you experienced to load data from server.
There are multiple ways you can go about this but at the end of the day you need an endpoint for your iOS application to talk to your web server. This can be done with a TCP connection (little more complicated) or with a RESTful HTTP API endpoint which is generally the way most developers will go.
To get you running up and quickly on the client side have a look at AFNetworking to do the heavy lifting on your HTTP requests. You will then need a URL on your website that the iOS application can query. Abstract things to keep your API on a different subdomain, say for instance by creating a subdomain to handle your API requests. A login example could look like this
http://api.mysite.com/login
For a PHP based REST API here is a tutorial for you, PHP API or you could use a Node.js framework such as Restify
The general practise is to use JSON encoded data when sending requests back and forth from the server, iOS 7 has built in JSON encoding/decoding, node and PHP also have pretty good support.
Once you are able to send and receive HTTP request from your iOS device to your web server it is just a matter of checking the username and password match up on the server side (seems you already know how to do this?) to the ones in your database and sending back a authentication BOOL and option error message if failed.
Assume that you have complete programmatic control over a wireless router (running say OpenWrt or DD-WRT - linux). The router is configured to broadcast an ssid, and the network is wide open.
A mobile user (iPhone/Android/BB) walks up.
1) on iPhone, if the device is not currently wifi connected, a dialog appears that offers to connect to available SSIDs. The user picks my ssid and connects. Is there a way, from my router (say using Bonjour or ??) to trigger the iPhone to launch the web browser and try to load the home page, or an autoconfig url automatically?
2) any different answer for Android/BB?
The reason is that in a 'walled garden' application I need to be able to pop up a greeting page and don't want the user to have to fumble around loading a default page first.
Any and all thoughts appreciated!
Thanks
RM.
Update - I think the answer may lie in either 802.21 or UMA. I read somewhere that ATT uses this with iPhones for authentication.
On iPhone there is a switch called 'autologin' when connecting to a wifi gateway. If you turn that on, the iPhone sends an HTTP request, and receives a redirect from my hotspot, and then I send the welcome page. (the spot is totally open). Problem is that iPhone seems to be waiting for something specific - it doesn't change from '3G' to wifi and may eventually time out. Also it still displays the 'Login' banner docked to the top of the window.
Anyone know of documentation for the frames I need to send to do a proper autologin?
What you're describing is a captive portal system (hotspot, walled garden, etc). This functionality can be implemented with several application on openwrt. Check out another answer for details on each specific option offered in openwrt Answer.
There are a few common techniques to implement a captive portal
HTTP 302 Redirect
The most common technique is to simply block all out bound traffic on the network and then redirect any port 80 traffic to your own portal page, either local or remotely hosted. This portal page would then provide the means to "authenticate" the user (by poking a hole in the firewall). There are layer 2 methods such as chillispot which provide all the same functionality and can be authenticated against a radius server if you wanted to get fancy.
DNS Rewrite
Another technique is to use dns rules to rewrite any dns query to resolve to your own webserver which will then present the user with a login page, once the user has "authenticated" you simply updates their dns, or allow the dns request from that user to pass upstream.
IP Redirect
This technique often times overlaps a bit with the HTTP redirect. Essentially you redirect their requests to a new destination IP. You could setup a squid proxy to then handle these requests.
Both iOS and android devices will detect for captive portals by simply checking for a standard URI resource (eg: http://www.apple.com/library/test/success.html) and if that resource is blocked then you're offline, if that resource gets 302 or 307 redirected then it assumes there is a captive portal in place and they will open a browser. If that resource is found then they assume you are online and no browser is auto opened.
Android will open the standard browser on the phone or tablet to allow the user to authenticate. iOS devices will however open a pseudo browser which is a limited application which doesn't allow things like video playback popups etc.
The WISPr protocol I believe was originally intended for devices which do not have a web browser to accept the terms and conditions and thus allowing these devices a generic protocol to accept and authenticate against a captive portal. I'm not even sure that the WISPr protocol was ever really accepted. (perhaps they redrafted it)
(Didn't realize how old this originally was, sorry)
Ok, solved it.
The protocol is called WISPr - now version 2.0
some links
http://erratasec.blogspot.com/2010/09/apples-secret-wispr-request.html
and traces
http://coova.org/node/4346
HTTP 302 Redirect
The most common technique is to simply block all out bound traffic on the network and then redirect any port 80 traffic to your own portal page, either local or remotely hosted. This portal page would then provide the means to "authenticate" the user (by poking a hole in the firewall). There are layer 2 methods such as chillispot which provide all the same functionality and can be authenticated against a radius server if you wanted to get fancy.
// Working on creating a wifi Hotspot, which would automatically trigger mobile browsers(directly to my shop's link) when the mobile device is connected to the wifi.. This would serve as an interesting factor to user's, get noticed something special about our Hotspot when they cross across it..
I think what you're looking for is the ability to create a standard wifi "hotspot".
There are several very good tutorials online about how to do this, several using DD-WRT.
For example, check out this one: http://www.hotspotsystem.com/en/hotspot/install_guide.html
which gives some examples.