API design: Auth0 for authentication and internal authorization - authentication

I am creating a iOS native app that talks to a Flask API.
My plan is to have the iOS front-end handle log in with Auth0 lock. Afterwards, the front-end would store the JWT in local memory and use that on every API request.
On the back-end I plan to have a User table with both an internal ID field and a Auth0 ID field. Per API request I would look up the user via the Auth0 ID and then use a library like flask-bouncer to handle resource authorization.
Is this a valid approach?
Are there any out of box features of Auth0
that I am rebuilding? If so what are the advantages of using the
Auth0 version?
Are there any future implications that I am missing
with this approach?
What are the advantages of using Auth0 instead of building it myself following something like this?
Anything else to consider?

Is this a valid approach?
Depends on what you call valid. But it would work, yes.
Are there any out of box features of Auth0 that I am rebuilding? If so what are the advantages of using the Auth0 version?
You're not using authorization using scopes. See Auth0's tutorial for Flask.
Are there any future implications that I am missing with this approach?
That's a broad question that I wouldn't know an answer for.
What are the advantages of using Auth0 instead of building it myself following something like this?
You do not have to worry about signup, login, verifying emails, bruteforce protection, resetting passwords, MFA, etc. You get all of those things out of the box. But... some more complex things might require additional effort on your side.
Anything else to consider?
Make a clear decision on where you're storing what info and whether you want to store your users in your database at all. An easy pitfall is to have multiple sources of truth for certain data that's both in Auth0 and your database (e.g. first and last name). Also see the User Data Storage Best Practices.

Related

Handling authorization with IdentityServer4

I'm extremely confused on how to use a centralized IDP with both authentication and authorization. The architecture for my project was to be a single web API and one React client. I wanted to keep things structured out into microservices just to try something more modern, but I'm having major issues with the centralized identity, as many others have.
My goal is fairly simple. User logs in, selects a tenant from a list of tenants that they have access to, and then they are redirected to the client with roles and a "tid" or tenant id claim which is just the GUID of the selected company.
The Microsoft prescribed way to add identity in my scenario is IdentityServer, so I started with that. Everything was smooth sailing until I discovered the inner workings of the tokens. While some others have issues adding permissions, the authorization logic in my application is very simple and roles would suffice. While I would initially be fine with roles refreshing naturally via expiration, they must immediately update whenever my users select a different tenant to "log in" to. However, the problem is that I cannot refresh these claims when the user changes tenants without logging out. Essentially, I tried mixing authorization with authentication and hit a wall.
It seems like I have two options:
Obtain the authorization information from a separate provider, or even an endpoint on the identity server itself, like /user-info but for authorization information. This ends up adding a huge overhead, but the actual boilerplate for the server and for the client is minimal. This is similar to how the OSS version of PolicyServer does it, although I do not know how their paid implementation is. My main problem here is that both the client and resource (API) will need this information. How could I avoid N requests per interaction (where N is the number of resources/clients)?
Implement some sort of custom state and keep a store of users who need their JWTs refreshed. Check these and return some custom response to the caller, which then uses custom js client code to refresh the token on this response. This is a huge theory and, even if it is plausible, still introduces state and kind of invalidates the point of JWTs while requiring a large amount of custom code.
So, I apologize for the long post but this is really irking me. I do not NEED to use IdentityServer or JWTs, but I would like to at least have a React front-end. What options do I have for up-to-date tenancy selection and roles? Right when I was willing to give in and implement an authorization endpoint that returns fresh data, I realized I'd be calling it both at the API and client every request. Even with cached data, that's a lot of overhead just in pure http calls. Is there some alternative solution that would work here? Could I honestly just use a cookie with authorization information that is secure and updated only when necessary?
It becomes confusing when you want to use IdentityServer as-is for user authorization. Keep concerns seperated.
As commented by Dominick Baier:
Yes – we recommend to use IdentityServer for end-user authentication,
federation and API access control.
PolicyServer is our recommendation for user authorization.
Option 1 seems the recommended option. So if you decide to go for option 1:
The OSS version of the PolicyServer will suffice for handling the requests. But instead of using a json config file:
// this sets up the PolicyServer client library and policy provider
// - configuration is loaded from appsettings.json
services.AddPolicyServerClient(Configuration.GetSection("Policy"))
.AddAuthorizationPermissionPolicies();
get the information from an endpoint. Add caching to improve performance.
In order to allow centralized access, you can either create a seperate policy server or extend IdentityServer with user authorization endpoints. Use extension grants to access the user authorization endpoints, because you may want to distinguish between client and api.
The json configuration is local. The new endpoint will need it's own data store where it can read the user claims. In order to allow centralized information, add information about where the permissions can be used. Personally I use the scope to model the permissions, because both client and api know the scope.
Final step is to add admin UI or endpoints to maintain the user authorization.
I ended up using remote gRPC calls for the authorization. You can see more at https://github.com/Perustaja/PermissionServerDemo
I don't like to accept my own answer here but I think my solution and thoughts on it in the repository will be good for anyone thinking about possible solutions to handing stale JWT authorization information.

Migrate user authentication to Firebase Auth

I'm a developer at a company that has an application that is built with PHP and MySQL. We have about 300 users that have their passwords hashed with bcrypt and stored in the users table. We're looking to rebuild the application with Angular and Firebase.
My question is, how to I migrate these users over Firebase and use Firebase Auth. It's easy to migrate the profile info over, but I want to be sure that the user can still use the same email/password when they login to the new application.
Here are some approaches that I've thought of. All of these are terrible in my opinion.
A) Create a custom auth system that uses bcrypt, and then just copy the hash over. This isn't what I want because I don't want to maintain a custom auth solution.
B) Every time a user logs into the old system, grab their password from the login field, store it in plaintext, then manually create each user in Firebase with their email/password. This would require 100% of users to login before we switch to the new app. That is unlikely. Also this is obviously a breach of privacy. I'm sure it breaks some sort of law or standard. But it works and it's a last resort option.
C) Every time the user logs in to the old system, send the email/password in plaintext to a script that auto-creates a new Firebase user with the same user/email. This would require 100% of users to login before we switch to the new app. That is unlikely. It's also harder to build than option B.
None of theses options look very good. They all have downsides. Is there a better option? If not, between B and C, which is most legal/ethical? Option B tempts me because it's super simple, but I don't want to break any laws or lose the trust of my companies clients.
[From Firebase Authentication team]
Firebase has a better solution. Firebase Authentication service has the capability to batch import password hashes of your existing users, for well known hash algorithms (hmac-sha256, bcrypt, scrypt etc.). End users just sign with their existing passwords, and your app will receive a Firebase token containing the same user_id you uploaded. None of the option A/B/C is needed.
[Update 11/19] The Firebase command line tool 3.2.0 supports importing bcrypt hashed passwords to Firebase Authentication service.
Disclosure: I work at Auth0.
Disclaimer: If you really set your mind on using Firebase from a practical point of view this might not help you as it focuses on what Auth0 provides to solve problems similar to the one you described. However, from a theoretical point of view this might help you so I deemed it worthwhile to share.
Enough with the legal stuff...
Check this guide for a fully detailed view on how Auth0 supports migrating users from your custom store to a hosted one.
... automatic migration of users to Auth0 from a custom database connection. This feature adds your users to the Auth0 database one-at-a-time as each logs in and avoids asking your users to reset their passwords all at the same time.
The approach would be similar to your option C, but the only thing that would need to stay from the old system would be the database. Everyone would start using the new application and the login would happen transparently for the users. Depending on the API's made available by Firebase, you could most likely implement something similar and that would be my recommendation.
Additionally, you should not even consider any process that includes manual steps and has to deal with plain text passwords.
A final note, excellent decision on rebuilding your app to use an external authentication service, even if it's not Auth0. :)
Authentication is a hard problem and wish more application developers stopped wasting time with issues totally unrelated to the business problems that their applications solve.
The Firebase CLI very recently added an auth:import command that allows you to import an existing user database into Firebase Auth from CSV or JSON.

Simple RESTful API authentication

I'm building a single-page web application, fully based on RESTful API. I've seen several topics in that matter, but some things remain unclear for me.
I will need users to log in. Here are some of my ideas:
I can send e-mail and password to API and use basic auth. I'm not sure where should I keep password, should it be encrypted and if so: how?
Can I use built-in session system instead? Is it wrong to use cookies directly in the RESTful API? Why is it so popular to send credentials/keys to API itself instead of using cookies?
I thought about having one API key per user, return it in login action and keep it in localStorage. I guess it's not the greatest idea to have just one key per user?
Then, I came up with idea to have separate keys table and add random keys each time somebody logs in. On logout, the key would go away and no longer be valid. This is more secure than previous idea.
How is it solved in simple projects? I'd like to make it simple but not ridiculously inserure.
Please help.
The commonly approach is to use the header Authorization in REST. The state of the application must be on the client side with REST and shouldn'a be tied to a particularly client kind (browser with cookies)
I think that this link could be helpful:
Implementing authentication with tokens for RESTful applications : https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
There is also à great question to à similar question here : https://softwareengineering.stackexchange.com/questions/141019/should-cookies-be-used-in-a-restful-api
Hope it helps,
Thierry

Smartsheet API Sign in.

Is it possible to use Smartsheet's API to sign into Smartsheet on the Web. I am thinking of creating a form-based auth that uses the API to login. Has anyone done something like this? or is this even possible with the tokens that can be produced by the API. I am aiming for a web based single sign on without using SAML.
I'm not totally clear on what you are asking, so I'll address each question individually in hopes that it addresses your overall question:
Is it possible to use Smartsheet's API to sign into Smartsheet on the Web?
No, you cannot create a web session using the api. For 3rd party apps, that would defeat the purpose of using OAuth2 since the whole goal with OAuth is to grant limited access to protected resources. For user-generated access tokens, it could be feasible, since those tokens have unrestricted access, but the API does not currently support that.
I am thinking of creating a form-based auth that uses the API to login. Has anyone done something like this?
I assume you mean you will create a form to collect a user's Smartsheet credentials and use those to have an SSO experience into Smartsheet? This is technically possible, but I'd strongly discourage against it. To create an SSO experience, you'd need to retain the password in a way that allows you to POST it on behalf of the user. This means you'd store it in a 2-way encrypted state (at best), which is definitely not best practice. Again, I'd highly recommend NOT doing this.
I am aiming for a web based single sign on without using SAML.
If you want an SSO experience into Smartsheet, you can either use SAML or Google (not truly SSO, but pretty close). There isn't an API-based approach currently.
Side note, if you want to go the other way, meaning you have a website and you want to use Smartsheet (or any OAuth2-based API for that matter) as the identity provider, you could use the 3rd Party OAuth2 flow. See the docs here. You could then add a "Login with Smartsheet" button to initiate that flow, much like we see everywhere on the web with "Login with Google" or "Login with Facebook".

User Authorization in iOS App

Assuming I want to create an app that allows users to login. The accounts are stored securely in a server. Some pages are also not visible to users who haven't logged in yet. Can someone guide me on how to do so? So like how to deal with "sessions" and all that. How would I do that if the database online is MySQL?
On another note, to implement "OAuth" the database has to be OAuth-compatible, am I right on this? And if so, how would I use OAuth on iOS? Is there an Apple API for that?
I appreciate any help / guidance
Thank you,
Let's do this part by part:
It doesn't matter what is powering
the server-side of things. Be it
MySQL, Oracle, SQLite, if you have a
dynamic language that connects to
that DB and outputs XML or JSON
data, you're set.
Dealing with sessions is easy. You
can use NSHTTPCookieStorage to
have that handled automatically for
you. Because sessions are set via a
cookie, any HTTP request will set
that cookie locally and send it in
future requests.
As far as permissions go, I would do
that validation server-side. Because
you have the session, and you should
know server-side wether the user is
logged in or not, just send a list
of pages the user can see.
There are a few OAuth libraries you
can use. The OAuth project lists a
couple that seem straightforward
enough to use. If you're looking for
Twitter integration however, a
question has been asked here
with pretty good answers.
Returning to the server-side of
things, this can be easily achieved
using a dynamic language such as PHP
or using the Ruby on Rails
framework. RoR is really good in
that aspect in the sense that you
can quickly bring an API up by using
its gems (Devise, OAuth2,
etc)