Firebase custom OAuth authentication - authentication

FireBase appears to support OAuth-based authentication from Facebook, Twitter, Google, GitHub. What about a different OAuth provider? It would be great if there were a generic "OAuth" option where in addition to specifying an API Key and Secret you specified whatever other information was needed.
Is it possible to use FireBase's existing OAuth-based authentication modules without rolling my own custom OAuth authentication module for FireBase, by possibly forking from one of the "built-in" OAuth mechanisms? Which one is the most generic, if so?

I also struggled for a while now with this, and here's how I've done it for my project. Run a node.js express server that will have the role to:
get the req from your frontend app
redirect user to oauth page
return to node.js in case of success/error and compute the token needed for firebase in order to successfully login the user.
res with a cookie containing this token and redirect the user back to frontend app to complete the process.
You will have to run the node server on a different vps in order for your app to work but you'll probably need it anyway if you have a bigger app that needs to run private stuff on the backend and not everything upfront.

Firebase has 5 OAuth-based authentication, Facebook, Twitter, Google, GitHub and Custom Auth for now. Using Custom Authentication Firebase gives you complete control over user authentication by allowing you to authenticate using secure JSON Web Tokens (JWTs). So you can specify additional options to API Key and Secret. For example:
var logInAndThen = function(options) {
var secret = '********************';
var tokenGenerator = new FirebaseTokenGenerator(secret);
var token = tokenGenerator.createToken(credentials[options.userType ||
'admin'
};

Related

Use react-native-firebase/auth OAuth provider to auth Azure AD credential

I am developing a mobile with react-native (react-native-firebase/auth) and using Firebase Auth to manage user login. In the beginning, I only use the email/password to auth users and work nice.
Now I would like to let users use Azure AD. Since react-native-firebase/auth does not support Microsoft account at this moment, so I use react-native-app-auth. Afterwards, use the Microsoft credential to auth the Firebase user and link them together.
const result = await authorize(config);
const credential = auth.OAuthProvider.credential(
result.idToken,
result.accessToken,
);
const userCredential = await auth().signInWithCredential(credential);
When calling the signInWithCredential, it throw an error : [auth/internal-error].
Currently, I have backend user profile like to a Firebase user account. I don't want to complicate the backend to have multiple auth methods. Ideally, it can be done at the Firebase would be great.
Thanks.
Seems like you have to use a custom token.
Unlike other OAuth providers supported by Firebase such as Google, Facebook, and Twitter, where sign-in can directly be achieved with OAuth access token based credentials, Firebase Auth does not support the same capability for providers such as Microsoft due to the inability of the Firebase Auth server to verify the audience of Microsoft OAuth access tokens.
If these providers are required to be used in unsupported environments, a third party OAuth library and Firebase custom authentication would need to be used.
source: Firebase doc

How to use Firebase Authentication with Okta?

I am currently using Firebase Authentication in my app using the built-in OIDC providers (Google, Facebook etc.). Is it possible to use Okta as an additional OIDC provider with minimal modifications to my app, meaning Okta should behave just like any other built-in provider? Firebase Auth apis, such as firebase.auth().currentUser and firebase.auth().onAuthStateChanged() should still work.
The doc page for Custom Authentication talks about getting a custom token from an auth server, but does not clarify if that's an OAuth access token. Is there an example of Okta integration or a generic OIDC integration that works seamlessly with Firebase auth?
There's no built-in Okta provider for Firebase Authentication, but if you have an existing authentication flow for it, it's fairly easy to integrate it into Firebase as a custom provider.
It's a 6 step process:
You gather the user credentials on the client.
You pass those credentials to a trusted environment, either a server you control, or Cloud Functions.
On the server you verify that the credentials are correct according to Okta, typically by calling a server-side API they provide with a key you provide.
You then use the results of that call to mint a new ID token for the user. This is a JWT, not an OAuth access token.
You pass back that ID token from the server to the client.
The client then calls firebase.auth().signInWithCustomToken(token) with the ID token, to sign in to Firebase Authentication.

Firebase authentication for private server

I am developoing a flutter app and want to use Firebase auth service to enable my users to signup/login using:
email/pass
google
facebook
I have a lumen backend REST server with MySQL database.
Problem: Going through loads of firebase documentation I cannot understand the whole flow of how this should work.
I can successfully create users using the app and they appear in the firebase console, however, I don't know how to enable them to securely talk to my backend server.
I would expect Firebase to release an access and refresh tokens for me to use for my private communication between the app and backend, like AWS cognito does. Instead, it issues an "ID Token" that is JWT token and should be verified on backend. But what do I do once it is verified?
How do I link my users in my database to the authenticated user? What is the thing to store in the database to map to the authenticated user?
Do I have to generate custom tokens via the Admin SDK?
Or is the ID Token the thing that should be passed from client to backend on each request and then verified? But still, what do I put from this ID token to my database to link the authenticated user with their data?
Here's how I do it now. It works great.
Install Firebase admin sdk on your backend server, if you are using php, here is what I've followed and worked flawlessly: PHP Firebase Admin sdk
Aquire firebase idToken using firebase SDK in your client (app), I've used Firebase auth package for this.
Send idToken to your backend
Use Admin SDK to verify the idToken, if verification is successful it returns a Firebase user object. And you can perform various management actions on it (modify, delete, get different data etc.).
Get uid from the Firebase user object.
Store uid in your database.
Now each time this authenticated user makes a request to your backend server, you attach the idToken to the header of the request.
Each time you verify (see step 4) the idToken on your backend server and if the verification is successful you extract the uid to know which user to query in your database.
Any comments/improvements on this are welcome :)

Using Google OAuth to secure web services in aspnet core

I'm getting lost in OAuth and OpenIDConnect and aspnet core middleware. Any help on this would be appreciated.
I have multiple UIs (web, native apps) that use the same set of web services, and I'd like to ensure only authenticated users can access the web services. My organization uses Google accounts, so I'd like to use Google authentication restricted to the organization domain.
The web site is properly requiring authentication, following this sample. What I need now is to have the web site (AngularJS 4) invoke my back end web services with an auth token that I can verify with Google.
The back end services are written with aspnet core. I've tried using these approaches: Google middleware and Google OpenIDConnect but these still 1) assume there is a UI that can prompt an unauthorized user to log in, and 2) appear to be cookie-based, and I won't have cookies for the web service calls.
I don't want to prompt the user to log in, since the "user" in this case is a software client. Either they're authenticated or not already. I just need to get the authentication token, validate it, and carry on.
This appears to be the same question, which hasn't been answered yet, either.
Any suggestions are appreciated. Also, suggestions or tips on having native apps do the same!
Got it working. As mentioned, I was getting lost, and the OpenIDConnect, though referenced in several areas as a solution, was a red herring for the web services. Here's what is working for me now, with as complete steps as I can provide (some cleanup required):
Add authentication to the UI following these directions
Obtain the JWT token as shown in the first segment here
On each web service call, include the JWT token in the headers:
Name: Authentication
Value: Bearer {token value}
Install the JwtBearer NuGet package
In the ConfigureServices method of Startup in the web service, after you AddMvc():
services.AddAuthorization(options =>
{ // this policy needed only if you want to restrict to accounts within your domain. otherwise, don't use options. or use whatever options work for you.
options.AddPolicy("hd",
policy => policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "hd" &&
("https://accounts.google.com".Equals(c.Issuer) ||
"accounts.google.com".Equals(c.Issuer, StringComparison.CurrentCultureIgnoreCase)) &&
c.Value == "yourdomain.com"
)));
});
In the Configure method, before you UseMvc():
JwtBearerOptions jwtOptions = new JwtBearerOptions();
jwtOptions.Audience = "{the OAuth 2.0 client ID credential from google api developer console}";
jwtOptions.Authority = "https://accounts.google.com";
jwtOptions.TokenValidationParameters = new TokenValidationParameters();
jwtOptions.TokenValidationParameters.ValidIssuers = new List<string>()
{
"https://accounts.google.com",
"accounts.google.com"
};
app.UseJwtBearerAuthentication(jwtOptions);
Perhaps there is a more appropriate way to do this...if there is, I'm interested in trying it out. For now, this is working.
I will try to help.
First you need to look at OpenID Connect (which is built on top of OAuth 2.0) remembering that OAuth 2.0 NOT an Authentication protocol.
1) assume there is a UI
No UI is required for login assuming you are using Google services. You only need to check for the existence of and validate the Access Token, Identity Token (and perhaps the refresh token). If there is no Token, assume the user is NOT Authenticated and redirect them to the Authentication Server with a Authorization Request.
If there is a valid Access Token and Refresh Token, then you can assume the user is Authenticated.
You can also inspect the Access Token for proper "Scopes" to determine if they are Authorized for your specific application.
If you are using Google for Authorization Server, you can validate the the hd parameter within Identity Token has the desired Domain.
BTW: No cookies involved.
Hope that helps.

Best practice to receive JWT from third party provider?

I am playing with JWT and expressJS to learn something new, and come up with the idea to make my little JWT provider to use for all my future personal projects.
The idea is quite simple, my provider will register with facebook and twitter API, and will use passport to authenticate with them. I will also store users credentials so I don't need to worry about that in my other projects (these project will hold their info about users but various data from socials/passwords etc.. will be in the provider).
I coded this little workflow:
I register the app in my provider with a callback url
Put a button (e.g. 'Login with Twitter') on my project, that links directly to my provider
when I accept the Twitter conditions, twitter callback calls my provider that pick the right user and redirect to my project.
I am stuck on this last point, I would love to pass to my project the JWT token to use for its next requests, but how do I pass to it?
Cannot set cookie because domains are different obviously, I am missing something? Did I follow the wrong way?
The authentication flow you describe is similar to OAuth2. I suggest to read the RFC 6749. It explain the technical details to implement it. You can also refer to OpenID Connect. It is an extension of OAuth2 using JWT
Basically you need to create an access token after a successful login and return a redirection to the callback url. The adapted flow to your context could be the following
App redirects user to central login form
The server prompts user for the credentials :It returns an HTML form with the supported authentication methods, that can include a connection with a third party authentication provider
After a successful authentication, the server creates an access token. It can be a JWT
The server returns a redirection to the provided callback url. It includes an authentication code
The app request the authentication server using the previous code and get an access token
The token can be used by app to access to a protected resource
In Oauth2, the access token it is just a random string, but you can use JWT perfectly.