0

I've tried to find an answer to this question for a while now, but my efforts have been fruitless. I've found several articles and questions about offline authentication, but these are mainly concerned with storing login credentials locally after a user has already logged in once online.

The reason I want to implement such a system is because certain groups should have access to my applications for free, whereas others which do not fall under these groups should have to pay in order to use these applications. To my knowledge this is not something that is supported by the app store. Additionally eventually the series of applications should support other devices, so it makes sense to have a common login service.

These applications don't need resources from a server. The server is used merely for authenticating the user.

When a user launches an app they must log in before they can use the app. The authentication takes place on a server and is already sorted. The question is how I can restrict use of the application, which is already installed on the device by the time the user is prompted log in. If this were a web application I would store a session cookie which is then used whenever a resource is requested. In my case all resources are already on the device, so if someone is stubborn enough they will be able to use the application without logging in first, but I don't want this to be too easy. If there is some offline equivalent of a session cookie that I can use to verify that the user has logged in as the app is being used that would be ideal. I'm not storing any sensitive information in the applications nor would it be a catastrophe if someone were to gain access without first logging into an account, but I would like to know if there is a good way to solve this problem.

  • When users launch my applications they should be prompted to login
  • After logging in users should be able to use the application, and it shouldn't be too easy circumvent the log-in process

I'm not asking for details, but I've hit a dead end and would like to know about any technologies or techniques that might help.

1

I think you have either over-complicated the issue in your head (common practice for us developers) or you have a design flaw in your system. Could be both.

Your question states:

How do I prevent users from using my iOS apps unless they have been authenticated on a server?

The answer to which is: don't allow the app to start until a user has logged in. When you start the app, start it straight to a login screen. But, it appears you already have that in place:

When a user launches an app they must log in before they can use the app

So, really your question appears to be:

how I can restrict use of the application...?

Your user accounts need to have roles. At minimum, a free and premium user role.

Upon successful authentication, the user should obtain a token, which gives them use of the app. For the purposes of this discussion, I'll say "unrestricted access to the app" to avoid the complexities of unlocking only this feature or that feature, which is completely possible depending on your architecture.

The token should not only give access to use the app, but also have an expiration option, but that's up to you. (If a free user is perpetually free, and a premium user is a one-time-fee yields a perpetual license, then expirations are not necessary).

Once the user logs in for the first time, your user authentication server will issue a token based on their role and status. If they are a free user, they will receive this token, which gives them unfettered access to the app. If they are a premium user, then the server will withhold the token unless the premium has been paid.

Although the implementation method is a little out of scope for security.stackexchange.com, I'll do a simplified version here because I think its part of the underpinnings of your original question.

The complication comes at this question: how do your premium users pay to unlock the app? You can't have a free and a paid app because everyone would just download the free one and never pay.

You're only left with the option of a single app and altering the user role based on a paid (or even subscription) status.

Since you've posted this in iOS, I'll reference In-App purchases. The app should be free by default with in-app purchase options. When a free user downloads the app, they can request their free account (or, if they belong to a given group that has a coupon code, etc... they need the option of entering that, which will change their role on your server to a free user role).

Otherwise, you can leverage the in-app payments to upgrade the account to a premium / unlocked version.

This being said, having an app be "free" and then immediately require an unlock code or an in-app purchase will be a "high friction" implementation.

If you decided to go with a free and paid version in the app store. The free version would simply require a coupon code to activate the free subscription. Or, in the alternative, it would have to wait for your staff to approve the new user. (Lots of work for a free app).

The paid version would work right after the download. Here, you're restricting the "high friction" implementation to users who are getting free stuff anyway. Paid users have a smooth as butter transaction.

The authentication takes place on a server and is already sorted

If your authentication server does not support roles, then this isn't sorted, which may be a design flaw that needs to be revisited. Especially considering that if you don't currently have user roles, you certainly would need to have code that either queries Apple's API for subscription status, or have code that receives an event when a subsciption / fee has been paid to change a user's role.

  • Thank you for the elaborate answer. Roles are definitely something that I have considered. For authentication I use an external service, which supports roles. I may indeed have over-complicated the issue, but what I'm worried about is how to prevent the received token from being forged. I need to validate the token in the application and a user should already have access to all the running code by the time they start the application. I'm worried that they'll extract information to forge such a token. – Slick Vick Aug 8 '17 at 10:27
  • This may indeed be something the operating system takes care of already, but I'm also worried that the application could easily be modified to bypass the login if it's merely a view that loads another view upon a succesful login. – Slick Vick Aug 8 '17 at 10:35
  • If you are worried about the token being forged, then use signing crypto to verify it. Issue the token signed with a given private key, which resides on your server (securely, not web accessible, this is a whole different discussion on its own). When you issue the tokens, sign the token with the private key. The app uses the public key to authenticate and verify it is authentic and untampered. Forged tokens will fail here, and can be safely ignored. – DrDamnit Aug 8 '17 at 10:58
  • Re: modding the app. All apps can be cracked. Disassemble, read machine code, insert jmp statement, re-compile, re-install. Viola. While this should be infeasible because the iPhone should only allow signed apps to install and run, your objective should not be to prevent hackers and crackers from getting into your apps. A rooted iPhone and a motivated hacker are all that's needed to defeat most copy protection / use protection. Your objective should be to raise the level of difficulty that paying for your app is a better option than cracking it. – DrDamnit Aug 8 '17 at 11:02
  • Putting my hacker hat on, it would be possible (for an attacker with sufficient privileges on their own iPhone) to swap out the public key in the app so that they could then forge a token, sign it with their own key, and activate your app. Honestly, if someone went through that effort with one of my apps, and it kept me from earning $4.99 from them, I think they've earned it. (Provided they cannot compromise sensitive data or other users data, which is not the case here. Your question stated that there is really nothing of sensitive in your app). So they broke into their own account. So what? – DrDamnit Aug 8 '17 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.