I intend to implement all my application logic online but I want to know if it's possible to make a phone number authentication on cloud functions with the auto verification callback.
The built-in providers of Firebase Authentication needs to be called from within the client-side SDKs. Signing in with these providers is not meant to be initiated from server-side code, even though the accounts can be read and manipulated from server-side code.
You can definitely implement your own phone authentication provider, and then use the Admin SDK to mint Firebase tokens for that.
Related
We have an auth infrastructure based on OAuth2 that is integrated into a variety of web apps within our organization. We also have a pure native application with no middle-ware of its own, and we want to integrate authentication into this native application. This application already has its own internal login mechanism with a native login screen, and we don't want to have it start launching external components like web browsers in order to display login windows. We are both the app provider and the auth provider, so the concern of the app having visibility into the user's credentials is less of an issue -- we trust ourselves to not intentionally do anything untoward with the user's credentials, and it's the same people writing a login form in the app as writing it on a web site. :-)
We are trying to figure out how best to support having the application continue to collect credentials the way it does now, but use them to obtain an auth token within our auth framework. With the APIs in place right now, the only way I can see for it to be done is to bake a Client Secret into the native app so that it can use a Resource Owner Password Credentials Grant request, since the code that would normally be making this call doesn't have a server side to live in. This feels really wrong, somehow. :-P
As far as I can see it, many of the structures of OAuth don't really apply to this app because it's not living in the context of a web browser, it doesn't have any concept of a "domain" nor any sort of "cross-domain" restrictions. It has been suggested that perhaps we create middleware for this app just for the purpose of exchanging authentication codes for tokens, but the rationale for that seems to be that this middleware theoretically ought to be able to somehow vet requests to determine whether they are legitimately from the application, and I don't see any way to do that that couldn't be faked by anyone with access to the client application code. Basically, the only purpose such middleware would serve would be to make the Client Secret irrelevant with respect to getting auth codes for credentials.
One thought that came to us was, how does something like Windows do it? Windows very obviously uses a native login form, but then some flow exists whereby the credentials that are entered are used for authentication and presumably, deep in the internals of the OS, for obtaining an auth token. Does anybody know if this architecture is documented anywhere? Does Microsoft's architectural choices here have any relation to OAuth2? What is the "best practice" for an application if you take it as a given that it doesn't have middleware and has its own native login form?
FWIW you don't need a client secret to use ROPC Grant to obtain or refresh tokens if the client is configured as a public client, i.e. a client that isn't capable of storing a secret.
RFC8252 OAuth 2.0 for Native Apps encourages using a native user agent for your scenario, using authorization code flows with PKCE. Authorization services like Okta and Auth0 have jumped onboard too, although they still recommend ROPC if the client is "absolutely trusted".
RFC6819 OAuth 2.0 Security discourages ROPC, but also says "Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization", which are first-party apps.
So while the security verdict seems to be that authorization code+PKCE is the best practice, the UX hurdle of showing a user a browser window to log into a native app seem to be keeping ROPC alive. It's difficult to tell if that UX is jarring because people aren't used to it or because people can't get used to it.
For authenticating end users to things like IoT services, many cloud services have a custom option: The client authenticates with the dev's own server (however the dev implements that), which in turn gets a token from the cloud service and sends that to the client for authentication with the cloud service. Amazon and Twilio are examples of this. This allows for a fully customizable auth.
If I understand correctly, Google Cloud Platform requires end users to authenticate with Google's OAuth2 service, meaning they must sign in with a Google account. I don't see any way around this, but the limitation is so severe that I wonder if I'm missing something. Is there some way I can instead authenticate users my own way?
meaning they must sign in with a Google account
That's not entirely correct, you probably overlooked this in the very doc you referenced (emphasis mine):
Firebase Authentication gives you a robust, secure authentication
system-in-a-box that helps you do sign in with any account your
users want to use. Firebase Authentication supports password
authentication in addition to federated sign in with Google, Facebook,
Twitter, and more, allowing you to easily scale your authentication
system as you grow on desktop and mobile.
So you can have your users choose their username and password or login using one of their supported 3rd party non-Google accounts.
But it will still be Google handling the authentication for you, which is good if you plan to use other GCP products/services as the authentication can be propaged.
If you want to handle the authentication yourself - nothing stops you from doing that, but it may be difficult/impossible to integrate it with other GCP products/services. The Plain OAuth 2.0 might be what you're looking for (I don't understand it enough), search for it in the Compare Auth Options guide.
I have a website and an API. The website allows anonymous people to browse the catalogue, but you must be logged in to post stuff.
I have built an API that exposes the same functionality. The API is used by a mobile app we are developing, but we are also going to allow other developers to use the API (i.e. it's publicly documented). The entire API is currently requires OAuth (2.0) authentication. To prevent abuse we use rate-limiting per OAuth client-id/user-id combination.
Now a new requirement for the mobile app has come down: The app should allow anonymous users to browse our catalogue. I am not sure how to implement this, without opening up our API to abuse.
Anonymous OAuth access
The first problem is allowing anonymous access. If we still want the entire API protected by OAuth then our mobile app will have to use the client-credentials grant type (posting a client-id and secret key). But we would have to store the client-id and secret in the app itself. This is not secure since it can easily be reverse engineered.
Alternatively, we could use dynamic client registration. As soon as an app is installed, it registers with an (undocumented) API to create an OAuth client for itself. Problem here is, how do I protect the client registration endpoint? A secret key again? Plus, this leads to a large amount of OAuth clients registered.
Remove OAuth from public endpoints
Alternatively, we could remove OAuth from the public endpoints all together (i.e. browsing the catalogue) and only require OAuth for posting stuff or managing an account. But how would I protect the API from abuse then? Without OAuth I cannot rate-limit based on client-id.
I am not sure that rate-limiting based on IP address would work. We expect many mobile app users and I fear that crappy (Moroccan) mobile telecom providers are NAT-ing a large amount of phone users behind just a few IP addresses. This would quickly exhaust any rate-limit that we set.
Is this correct? Or can I safely rate-limit on IP address for mobile users?
Alternative security mechanism
I could also implement a different authentication mechanism alongside OAuth. Something that allows our mobile phone app access to the API, which can distinguish (and rate-limit) different phones/users but which is safe from people just extracting a shared secret key from our mobile app binary.
Any suggestions on how to allow anonymous access to my API but still rate-limit effectively?
Since, the mobile app is installed on a device, if you configure a secret, then that secret will be common for all installations of the mobile app. Thus, derailing the purpose of a secret.
You should do dynamic registration. Here are the steps
Developer preconfigures the the following information with a trusted authority.
{
"software_id":"COMMON_VALUE_HERE",
"software_version": "OPTIONAL_BUILD_VERSION",
"client_name":"HUMAN_READABLE_CLIENT_NAME",
"client_uri":"OPTIONAL_FOR_CLIENT_CREDENTIALS",
"logo_uri":"OPTIONAL_FOR_CLIENT_CREDENTIALS",
"tos_uri":"OPTIONAL_TERMS_OF_USE"
}
The trusted authority generates a "software_statement" in exchange of the information that the developer provided. This contains the information that is constant for all installations of the native app.
After the app is installed on the user device, the app contacts the Authorization server for dynamic registration. The app posts the following to Authorization server
{
"redirect_uri" : "OPTIONAL_FOR_CLIENT_CREDENTIALS",
"scope": "SPACE SEPARATED SCOPES",
"software_statement": "MANDATORY"
}
The Authorization server verifies the information present in the "software_statement", generates and returns back a "client_id" and "client_secret" that are specific to the particular installation of software.
The client calls "POST" method on token endpoint with the newly received "client_id" and "client_secret", and receives an "access_token".
The client uses the "access_token" for accessing the "protected_resource".
The source of my answer is "oauth 2 in action" by Manning publication.
I have hosted a web service on App engine cloud endpoint. The APIs are protected by Auth2.0 as google say but for google accounts.
What I want to achieve is allow these APIs to be accessed using 3rd party tokens. Lets say I have my on Authentication server also providing User Management. I want my google endpoint APIs to be access based on the 3rd party token I provide at the time of API call.
Is this possible?
If Yes, Where should I write the mechanism to verify the clients authenticity and hint of how its to be done.
Also is there any demo project available that provides user management and authentication server and returns a token that can be accepted by App Engine.
Yes
On your app engine project, create the authentication mechanism to validate clients.
As such, there is no single solution available for User management, Authentication Server and Token Issuance, but separate modules are easily available.
I am struggling with understanding how to implement the following in Web API 2's OWIN pipeline.
I am building an application that will allow users to log in with several third-party identity providers such as Facebook, Twitter, LinkedIn, etc. However, I want the authentication step to be performed entirely client-side. For example, Facebook provides developers a snippet of markup and JavaScript that perform the authentication within the browser, resulting in a Facebook access token--all without any calls to my API.
The Web API templates that ship with Visual Studio 2013 all seem to assume that the API itself is in charge of the authentication flow. I have successfully gotten this style of authentication working, but in my opinion it is not the responsibility of the API to perform this work.
Here is the approach I have been trying to implement (so far unsuccessfully):
Provide endpoints like /authenticate/facebook that accept the appropriate access token and return a JWT with "decoded" claims if the access token is valid. This JWT would have similar claims regardless of the third-party identity provider. For Facebook, I think this involves a call to Graph API's /me endpoint.
Store the JWT in the browser's localStorage for subsequent API calls
Send the JWT in the Authorize header for each API call
Avoid cookies if at all possible
My questions:
Is this an appropriate way to handle third-party authorization?
Should the JWT's expiration match the third-party access token's? I assume yes, but I want to be aware of any caveats here.
Where and how do I store the third-party access tokens for use on subsequent API calls? Do I include them with the JWT?
Is there a template I can use out-of-the-box, or perhaps an online resource that implements authentication and authorization in this way? I don't understand how to use Web API's many classes and features to implement this.
I have this mostly figured out now. I believe my architecture choice is the correct one after much research, specifically into the so-called "assertion flow." I am using Thinktecture's Identity Server 3 project to act as my STS. I am using a custom implementation of ICustomGrantValidator to perform the validation of the Facebook access token and conversion to claims.