2-Step Verification - ensure that user is still authenticated in further sessions - java

I'm not sure about this issue I have, so maybe you can help me.
I have build a 2-Step Verification for an android app.
User sends his phone number from the app to the server via https
Server sends authentication code back to user via SMS (based on
Twilio/PHP)
User receives the code and can authenticate himself on
the server
At that point I can be sure that the user is the authenticated owner of the smartphone where the code has been sent.
If the user now restarts his phone and his app afterwards, how can I ensure that this user is still the same authenticated user?
Do I have to send some kind of credentials to the server each time based on the authentication code? Is this a safe and proper way to do this?
Thank you and best regards!
Dopser

A token number can be generated (similar to a cookie) which is stored both on the phone as well as the server database. The token number can be the verification code too, if you want to reduce the hassle of keeping track of another number.
You can store this token on your device using sharedpreferences or sqlite database, etc
Storage options on Android
On every onCreate() instance you can check if both the tokens match.
This way you can solve your issue.
You can do the same for all consequent activities.

The user should send the access token on each request.
You might need to consider the OAuth flow because your flow can be map to an OAuth token authentication. See here http://oauth.net/2/
You need to think about token/code validity in time as well.
Hope this helps.

Related

Which would be the right way to Sign-In on my own server from an native Android app?

I have a website and my own server and database, I also have an native Android app. I need to allow users to be able to sign-in with their account from the website inside the app in order to sync information and other things they need to use. I've been stuck for a couple of days trying to figure out how to do that. I've found a lot of content regarding OAuth and AppAuth but they are focused on using an OAuth API to the job. Back on my server, I use Hybridauth for social login, but users can also register directly on the site. How would be the proper way to allow my users to sign-in to their website account through the Android app?
You're overthinking it. OAuth isn't meant for users to log in, it's meant to enable external services to access data on behalf of a user.
To make a user log in? Create a POST endpoint on your webservice named login. It should take two parameters- username and password. The body of the login service should salt and hash the password, then check if the hash equals the hash stored in the db for the same user. If so, you're logged in and you return a success packet with a unique token to authenticate you for later requests. If not, you return a failure. The Android app would ask the user for their data, then send a request to the endpoint. On success it saves the token and sends it in all future requests to authenticate yourself, either as a parameter or as a header.
This is of course the simplest possible version. More advanced features would include expiring of login tokens, refresh tokens, possible lockout if you have too many bad requests, etc. But the above is the basic idea. Although really I'd look for an open source solution you can take, as there's quite a lot of complexity when you get into all the stuff mentioned above, and its a place where a mistake that leads to a vulnerability is probably the most dangerous.

I have a existing laravel Web App we wrapped in an android application, and need to save user logins

We have an existing web application we developed and needed to port over to an android application for people in the field. So we have a shell of an android application that just points to the URL and displays it. I want to save the user credentials so if they timeout/close application and re-click the application it will auto log them in always after the first time.
I am looking at SharedPrefrences as other threads here have done, but not sure how to capture the creds from the web input elements. Can I use SharedPrefrences to accomplish this still? If so how do I target that input?
You do NOT save the user credentials. Ever. Saving them means they can be read by malware. And no, encryption can't help as the encryption key would need to be in your app or on your filesystem.
Instead, you have your login API return a token. This token will be sent back to the server with every request (either as a parameter or a cookie). The server will then use this token to look up the user id on the server and figure out who it is. That token can be saved to SharedPreferences. (This is the simplest version, there are more advanced things you can do as well, but this is sufficient).
Why is this safer than storing the password? Because passwords can and frequently are shared between multiple apps, so losing a password can compromise multiple accounts.
BTW, this is also how webapps work. They don't send the username/password with every request, when they login a cookie is saved with a token, and its sent back with every future request.

Spring Boot + Ionic application authentication

I am developing a hybrid application with the use of Ionic 3 which will communicate with a REST Api service that I will write with the use of Spring Boot.
I am having some difficulties with setting up a proper registration / login mechanism. What I want to achieve is that the user registers on the mobile application, then logs in with his username and password and then whenever he opens the app he will always be logged in (without the need to pass the credentials again) for as long as he does not click the "log out" button.
The way I have tried is that with the help of Spring Secutiry when the user logs in with his credentials he receives a JWT token which is saved on the client side (app side) and then used in the header for each subseqnet request.
The problem that I have with this solution is that I have to setup the JWT expiration date (like 10 days, 30 days) and then, when that time passes, the user will have to enter his credentials again in order to receive a new token. I would like to avoid that. Another issue is that there is no mechanism to invalidate JWT tokens in case there is such a necesity.
Another option would be I think to set the access token validty for like 30 minutes and then receive a new one with the refresh token. This however, requires also the client id and client secret, which again, I don't think are safe for storing in the client application.
What is the best practice for such a case?
Please help and thanks :)
Storage module from Ionic can be helpful.
Idea : First time send authentication request
If data is authenticated save the response in local storage (Basically user data)
If user logs out you can remove the storage.
More information can be found on
Ionic Storage

Serverside OAuth Login

I am getting confused.
I have to write an Java Serverapplication for an mobile application. We have our own user management in that application, meaning the user can register and login on our servers without using an OAuth-Provider at all.
Now I want the user to be able to alternativly register via an OAuth Provider.
These are the options I see:
Let the user register local only.
Advantage:
The mobile applications can use the frameworks which are able to login and retrieve an access token for our application
Everything is prestyled by the platform itself, so no GUI work on that
Disadvantage:
How does the server know if the user is logged in or not? One way to figure that out could be to send the access token to the server and let the server start a request to the provider to check if the token is valid or not.
For the registration I have to send all user information which the client got from the provider to our servers.
I dont like this option, cause I would send Userdata and Accesstoken arround. Yes, it would be crypted via https of course, but it just feels wrong.
Let the user register via our servers
The user requests the OAuth provider itself to retreive the code with which you could request the access token.
Send this code to the server and let the server retreive the acess token.
Advantage:
The Server can be sure now, that the user is logged in
The server can retreive all user specific information about the user (such as username etc) from the OAuth provider itself, without sending the arround.
On a login you can repeat this, to make sure that the user is logged in correctly
Disadvantage:
I have to write the OAuth connectors (or using some library for that)
We are not able to use the sdk's, cause they're just returning the actual access token.
We still prefer the first option (register local only)
Because
they WANT to use the sdks. "'cause everyone does it."
If the user would start the application the first time and he was logged in already (with i.e. the FB client), he just has to accept the scopes, we setted up for our application.
Easier to handle the actual login, cause the sdk's where made for it
Does anyone know how to do something like that correctly? Both solutions seem a bit wrong to me.

How to secure Android App that pulls data from OAuth protected resource

My company is building a RESTful API that will return moderately sensitive information (i.e. financial information, but not account numbers). I have control over the RESTful API code/server and also am building the Android app. I've setup the API to use OAuth 2 with authorization code grant flow (with client ID and secret), and I auto-approve users without them having to approve the client since we own both client and provider. We use CAS for SSO and I am using this for the Authorization server as part of the OAuth 2 process when the user logs in to retrieve the token.
I am contemplating various ways to secure the data on the Android app. I've concluded that storing the client id and secret on the device is definitely not going to happen, but am thinking that storing the auth token might work, since it is only risk to the individual user (and really only if they happen to have a rooted phone).
Here are two options I have thought of. They both require me to have a sort of proxy server that is CAS protected, does the dance with the API server, and returns the auth token. This gets rid of the need for storing the client id and secret in the app code.
Here are what I've come up with:
1) Require the user to enter their password to access data each time they startup the App. This is definitely the most foolproof method. If this were done, I'd probably want to save the userID for convenience, but in that case couldn't use the CAS login (since it's web-based). I might be able to use a headless browser on the backend to log the user into CAS and retrieve the token based on what they enter in the Android form, but this seems hacky. Saving the userID is similar to what the Chase app does (if you happen to use this one) - it saves the userID but not your password between sessions.
2) Store the auth token on the Android device. This is a little less secure, but almost foolproof. When the user starts the app for the first time, open the webpage to the CAS login of the proxy server that returns the token (similar to https://developers.google.com/accounts/docs/MobileApps). After the user logs in and the token is returned to the app, encrypt it and store it private to the application. Also, use ProGuard to obfuscate the code, making the encryption algorithm more difficult to reverse engineer. I could also work in a token refresh, but I think this would be more of a false sense of security.
3) Don't use CAS but come up with another way to get an auth token for the service.
Any advice of how others have implemented similar scenarios (if it's been done)?
Thanks.
Well the reason why standards like OAuth are developed is that not everyone has to rethink the same attack vectors again and again. So most often it is your best choice to stick to something already available instead of baking your own thing.
The first problem with clients that are not capable of secretly storing data is that the user's data could be accessed by some attacker. As it is technically not possible to prevent this (code obfuscation won't help you against an expert attacker), the access token in OAuth 2 typically expires after short time and doesn't give an attacker full access (bounded by scope). Certainly you shouldn't store any refresh token on such a device.
The second problem is client impersonation. An attacker could steal your client secret and access your API in his own (maybe malicious) app. The user would still have to login there himself. The OAuth draft there requires the server to do everything it can to prevent this, but it is really hard.
The authorization server MUST authenticate the client whenever possible. If the authorization server cannot authenticate the client due to the client's nature, the authorization server MUST require the registration of any redirection URI used for receiving authorization responses, and SHOULD utilize other means to protect resource owners from such potentially malicious clients. For example, the authorization server can engage the resource owner to assist in identifying the client and its origin.
I think Google are the first to try another approach to authenticate a client on such devices, by checking the signature of the application, but they are not yet ready for prime time. If you want more insight into that approach, see my answer here.
For now, your best bet is to stay on the OAuth way, i.e. having the access token, client ID and client secrect (when using the authorization code grant flow) on the device, and configure your server to do additional checks. If you feel more secure obfuscating these, just do it, but always think of it as if these values were publicly available.

Categories