I have a simple Google App Engine backend (written in Python) for an Android client. All the backend is responsible for is accepting a key and returning a value; it is a classifier in general, implemented simply by looking up the key in a Cloud SQL table, though this specific behavior will change in the future.
The backend and client communicate via Google Cloud Endpoints. I want to restrict access to my backend's API to only accept requests incoming from my client, and am wondering if OAuth 2.0 is really the way to do this.
I don't need any contextual or extra information from the user, and as such, don't want to have user action to grant any type of authorization. All I need to do is be certain the request came from my app. I was considering simply generating a static key and hardcoding it in my client and backend, but I thought there must be a more elegant way to do this.
TL;DR: How can I restrict access to my backend only to my client/app without needing user context/input, by OAuth 2.0 or otherwise?
I don't know if the OP solved their problem but I am posting this here for others. I have wasted quite a few hours on this particular issue.
Steps :
1.Create an oAuth 2.0 client ID for your Android client.
2.Specify the Client IDs in the allowed_client_ids argument of the endpoints.api. In this case (Android), supply both its Android client ID and a web client ID in allowed_client_ids.
3.Supply the audiences argument as well in endpoints.api which is set to the web client ID.
4.Add a user check to the protected methods.
5.Redeploy the API backend.
6.Regenerate the client libraries.
Related
I'm writing an API, that will be used by a webapplication and native iPhone and Android apps.
The users will create accounts, login, logout etc, either through the webapplication or native apps. But all the business logic is in the API. Thus, the webapplication and the native apps are mostly thin layers containing only UI to integrate with the api.
Question:
What are some general ways/technologies used to authenticate users against the API, when you have this outer layer of either a webapplication or a native app.
Related questions
Authenticating users in iPhone app
Disclosure: I work at Auth0.
Tokens! Tokens! Tokens!
The most widespread approach to authenticate users in a Web API is through the use of token-based authentication. The procedure can be reduced to these steps:
The client application includes a token in the request (Authorization header).
The Web API validates the token and, if valid, processes the request in accordance to the information associated with the token.
This type of token is usually referred as a bearer token, because the only thing that an application has to to get access to an API protected resource is provide the token. The use of HTTPS with this type of authentication is vital in order to ensure that the token cannot be easily captured by an attacker when traveling from client to server.
The token can be classified further either as:
by-value token - associated information is contained in the token itself
by-reference token - associated information is kept on server-side storage that is then found using the token value as the key
A popular format used for by-value token is the JWT format (Get Started with JSON Web Tokens) given it's encoded in a Web friendly way and also has a fairly concise representation in order to reduce overhead on the wire.
Choosing between by-value or by-reference token is a matter of considering the pros and cons of each approach and review any specific requirements you may have. If you go with JWT, check jwt.io for reference on libraries supporting this format across a wide range of technologies.
How does my application get the tokens in the first place?
Setting up your API to authenticate users with tokens can be seen as the easiest part, although the need to think about all the usual security precautions still applies.
The biggest issue with token-based authentication system, is putting in place a system that can issue tokens to your different client applications that may use different technologies or be in completely different platforms.
The answer to this, as mentioned on another answers, is to rely on OAuth 2.0 and the OpenID Connect protocols and do one of the following:
Implement an identity provider/authorization server system compliant with the mentioned protocols
⤷ time consuming and complex, but you're following standards so you're less likely to mess up and you'll also gain interoperability
Delegate the authentication to a third-party authentication provider like Auth0
⤷ easy to get started, depending on amount of usage (the free plan on Auth0 goes up to 7000 users) it will cost you money instead of time
You should check out
OpenID
OAuth
and have an Identity Server set up.
Depends on what technology you are using, IdentityServer is widely available
one is IdentityServer4 on a .net platform
Please do not hesitate to ask more! :D
I agree with #Fabian Bettag and #WickStargazer.
You can use OAuth 2.0 which works very well with web-app, mobile client and java-script client. Also you can use OpenID Connect to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an inter-operable and REST-like manner.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol.
Note :- You can also implement SOAP for login,registration and logout(Security sensitive APIs) to add more security to your app.
Hope this will help and let me know for any help. Happy coding!!!
I am developing an Android app that integrates with users OneDrive for Personal account and obtains a Files.Read scope.
I have registered the app on Microsoft Application Registration Portal. Got a Client ID for authenticating my app with OneDrive and I am using Microsoft Graph APIs.
Now I have to include that Client ID in my app which would be distributed through Google Play.
How safe is that? If anyone can obtain that Client ID, is it possible for them to temper with the user's data by sending fake requests using that Client ID?
Please note that this concern is specifically for Client ID to authenticate requests to OneDrive.
Also, do these answers holds good here ?
Answer 1: https://stackoverflow.com/a/37945932/1363471
Just a remark: the client ID is not a secret by design, so actually
there is no need to protect it.
See section 2.2 in RFC 6749 ("The OAuth 2.0 Authorization Framework"):
The client identifier is not a secret; it is exposed to the resource
owner and MUST NOT be used alone for client authentication.
Answer 2: https://stackoverflow.com/a/14565249/1363471
I know this won't be a good StackOverflow answer, but I don't feel
able to explain it better than the Threat Model and Security
Considerations (RFC 6819). So here is the paragraph about obtaining a
Client Secret and its relative consequences.
Note that an Android app is a Public Client (a Native Application to
be more specific) so, as you say, unable to keep confidential its
credentials, but still able to protect Tokens and Authorization Code.
Answer #1 is correct, the Client ID is not a secret and you shouldn't be worried about packaging it inside your app. Its goal is to identify the client making the request, e.g. your app, not to authorize the call. The access token, which you get as the output of a successful OAuth flow and should be able to protect, is what's used to authorize the call.
I'm working with mobile apps and RESTful APIs and I have some doubts about security when registering a new user. I'm developing an android client that will communicate with a backend through REST requests.
It is very clear to me about the usage and implementation of the OAuth Authorization Server and how the communication is made between the android client (frontend) and the resource server or the authorization server (backend).
Most of the documentations mention that the client_id and client_secret must be stored in the server instead of the mobile app to avoid that such data to be figured out in an eventual decompilation proccess.
If I wish to perform an activity to create a new user, directly in the app (as it is the case in apps like snapchat, pinterest and so on), how could I perform the communication of the client with the REST API without the client_id and client_secret (or any kind of credentials) in the app?
The first and easiest solution would be to redirect the user to a signup webpage, but how could it be made in the APP?
https://stackoverflow.com/a/14572051/5055317
Simple answer: no data on the .apk is safe.
There are many ways to hide your API keys inside the apk. For example, using obfuscators like ProGuard/DexGuard, using Base64 encoding or hiding these Strings with JNI. But at the end they just create some delay to obtain the keys.
The only way to keep this information safe is if it is stored in a server, and your app gets it when needed.
Here is an article by Michael Ramirez review about hide techniques: https://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/
And here a discussion about this topic with some google employees: https://groups.google.com/forum/#!topic/google-places-api/SmujrL-pDpU
I don't know whether i am asking a stupid question here.
I am just starting to learn and program android applications.
I wondered :
How is the mechanism of an application and its back-end server works?
How to have a user login and only the contents related to that user is shown?
Which is something like when we login a Facebook account, we will have access to our information only.
Had a looked at SQL server and Data store and it seems like the database is shared for everyone using the application.
Android supports client apps, AppEngine supports server apps, communication between them is HTTP(S).
Endpoints are libraries of client code generated from server projects. Endpoints perform authentication by passing client credentials to the AppEngine server. Client app developers use Endpoint libraries instead of developing networking software themselves.
One of the AppEngine services is the optional Users Service to look up information related to the client credentials. If a server app needs to implement access control, it can be programmed to accept or reject requests per request detail and per user. The application author is responsible for implementing such security.
I am in the planning phase a new project. I want to be able to control multiple relays from my android powered phone over the internet. I need to use an HTTP based server as a middleman between the phone and the relays. Django is my preferred platform because Python is my strongest skill set. This would not be a "web app" (with the exception of the admin interface for managing the user and their access to the relays). Rather, the server would simply provide an API in the form of HTTPS requests and JSON encoding. Though, I should note that I have never done any web development in my life, so I don't know best practices (yet). The authentication method should meet the following criteria:
Works over HTTPS (self-signed SSL)
Provides multi-factor authentication (in the form of something you have and something you know)
Be reasonably secure (Would be very difficult to fool, guess at. or otherwise bypass)
Is simple in implementation for the server operator and end user on the mobile client
Is lightweight in in terms of both CPU cycles and bandwidth
I plan to use the following scheme to solve this:
An administrator logs into the web interface, creates a user, and sets up his/her permissions (including a username and a password chosen by the user).
The user starts the client, selects add server, and enters the server URL and his/her credentials.
The client attempts to authenticate the the user via HTTP auth
(over SSL). If the authentication was successful, the server will generate an API key in the form of a UUID and sends it to the client. The client will save this key and use it in all API calls over HTTPS. HTTP auth is only used for the initial authentication process prior to reviving a key, as a session scheme would not be nessessary for this application. Right? The client will only work if the phone is configured to automatically lock with a PIN or pattern after a short timeout. The server will only allow one key to be generated per user, unless an administrator resets the key. Hence, simple, mobile, multifactor authentication.
Is this sound from a security standpoint? Also, can anyone point me to an example of how to use the HTTP auth that is built into Django? From a Google search, I can find a lot of snipits witch hack the feature together. But, none of them implement HTTP auth in the wayit was added to Django in 1.1. The official documentation for REMOTE_AUTH can be found here, but I am having difficulty understanding the documentation as I am very new to Django.
I'm not entirely sure of how basic auth would work on Django, but I can take a shot.
The basic auth article on wikipedia covers a pretty standard usecase for logging in. For Android I've personally skipped the first part (401) and just pass my credentials in right away.
With your auth request you will have to just grab the user credentials from the request headers (WWW-Authenticate) and then do all the necessary work for that. With the credentials you can then just use the authentication framework provided in Django to verify that the user then generate their UUID (I guess).
As for basic auth on Android it's a little bit tricky at first and may leave you pulling your hair. I've found this article on Basic HTTP auth for android which helps explain how to do it.
As for the security part of it, I'm not too sure. It's pretty simple, which I'd say is a good thing :)