Client sends username and password to the server.
Server then checks if this user is authenticated.
If yes, the server returns an access token for the client...
Then user can use this access token to access protected resources...
The advantage here, is that we are not sending user info via API calls, and the access token will not last for long time, so hackers won't be able to find out user authentication info (user name and password), and if he finds out, the access token won't last long enough to do anything with it.
That's how I understand Laravel passport API security.
The confusing thing here, is that on first API call, user has to send user name and password, so hacker still have big chance to find out user info!!!
I know that there is something wrong with my understanding, and that's why I get confused, any explanation would be very appreciated.
There must be a way to prove your identity to authorization server, and one way is to provide username and password. The way you're gonna achieve communication between authorization server and your client application is totally up to you as long as it uses HTTP. As stated in RFC-6749:
This specification is designed for use with HTTP ([RFC2616]). The
use of OAuth over any protocol other than HTTP is out of scope.
Of course it's always advised to use HTTPS whenever possible. Just because HTTP is mentioned in document, doesn't mean HTTPS cannot be used because HTTPS is just encrypted version of HTTP.
Other thing I wanted to mention is that you don't need to provide username and password, there are several grant types where you can, for example, instead of username and password you can provide client_id and client_secret which is used in Client Credentials grant type.
If you are new to this I believe this all is little bit confusing for you. To summarize the purpose of OAuth2 to you (as far as I get it), is:
To separate role of the client (which can be browser, mobile etc.) from the resource owner (usually the owner of account). Why? Because if there is no separation, the client has access to user's sensitive data.
Imagine that the first point is secure enough for communication. But what happens if someone gets their hands on the session you have? They have access to all! This is why OAuth introduces scopes, where depending on the scope user has with provided access token has limited access to resources. Scope can be read, write, share etc. - this implementation is up to developer. So if someone gets their hands on your access token, because of scope they only have a limited access to resource.
These are one of my reasons, while RFC-6749 has better explanation:
Third-party applications are required to store the resource
owner's credentials for future use, typically a password in
clear-text.
Servers are required to support password authentication, despite
the security weaknesses inherent in passwords.
Third-party applications gain overly broad access to the resource
owner's protected resources, leaving resource owners without any
ability to restrict duration or access to a limited subset of
resources.
Resource owners cannot revoke access to an individual third party
without revoking access to all third parties, and must do so by
changing the third party's password.
Compromise of any third-party application results in compromise of
the end-user's password and all of the data protected by that
password.
To learn more about OAuth2, it's grant types and purposes, I recommend you to read this:
An Introduction to OAuth 2
Mentioned RFC-6749, even though it can be difficult to read because of technical writing.
Hope I clarified at least a small piece of blur.
Related
Plaid and security newbie here.
From what I understand, access tokens are valid indefinitely, granting the user access to information regarding one of their accounts.
Each account possesses a unique access token, and the tokens can only be invalidated either through the 'delete' request or through a user changing their password for that specific bank/account.
I'd like to keep them secure, and reduce the risk of them being accessed by hackers/nefarious actors, etc.
What would be the best way to store them though?
From what little I know, it might be best to keep them in the backend and use them when needed to access user data on request, then send that resultant data to the frontend (with other protections in place like verification and authentication of the user).
Is there a more secure way to store them? Perhaps to encrypt them between calls?
And a follow-up, any thoughts on storing these tokens in something like Supabase? From what I've read and seen, Row Level Security might help mitigate some of the risk, no?
Your general thinking seems right to me -- access tokens should be stored in an access-controlled database on the backend and never stored on the client side. Encrypting access tokens at rest is recommended but not required. As you think about your security model, note that that the access token alone doesn't grant data access -- the access token + API client ID + API secret key combination is required for data access.
As an authentication, the application (Service-X) uses a third-party internal service (Service-Y), in which all the information about the employees is stored. All internal services of the company use SSO.
How to implement the ability to log in to Service-X if Service-Y is unavailable? (If I have already been authenticated in Service-X before this).
The remember-me feature that comes with Spring Security might be what you're looking for.
However, there are still quite a few limitations to this. If your cookies are wiped upon closing the browser, which is quite common in a lot of big companies, this won't work. Other than by the session cookie, you can't safely remember the user. You absolutely require Service-Y to be available to identify the user if his cookies have been cleared or have expired.
The main selling point of OAuth2 is that you sign in using Service-Y without Service-X knowing your username/password (unless the username is transmitted through the scope), so while you could ask the user to provide a password on the first time he signs in Service-X using Service-Y in case Service-Y goes down, which would potentially patch your issue, I really do not recommend it because it somewhat defeats the purpose of OAuth2.
Now, if you do take that suggestion despite me not recommending it, you should make sure that Service-X checks that Service-Y is down before allowing the user to sign in using the password he provided for Service-X.
Best case scenario, if your browser cookies aren't cleaned, go for the remember-me feature. I suggest you read the following: http://www.baeldung.com/spring-security-oauth2-remember-me
I'm fairly new to Oauth2 and it seems I'm stuck.
To protect our API, we use OAuth2. We have a lot of calls that contain information based on an account, se we use the password grant in OAuth.
But, I also have to protect my registration call, so only registered applications with valid client_id and client_secret can use that call. So, after reading a while, it seemed that I needed to use the client_credentials grant for those calls.
But now, I have absolutely no idea how I can define witch call should be using password of client_credentials.
Am I thinking wrong and is it impossible to use a specific grant for a specific call, or how can I define when to use what grant?
FYI: I'm using Laravel5.1 and Luca Degasperi's Laravel OAuth2 server
Thanks!
Usually you won't limit calls or routes to specific grant types and for several reasons it's nearly impossible to limit the client-application access via oauth grants.
So as a rule of thumb you should only expose the endpoints the user is allowed to access doesen't matter which client is used.
Further more I would prefer the client credentials or owner credentials grant, it's better in facts of usability and security (Change Password, Remove Access for specific apps, ...) more about the different grants.
I'm a little new to this and please bear with me if I ask dumb questions.
As what I know, session is something saved at server (either in file or in database), and client access it via sessionid saved in cookie. To keep user login information, we can simply put a 'logged_in' column and an 'expired' column in session file or session table.
As far as I know, Oauth2.0 is designed for third party client to access the server. The whole process is controlled by an access_token, which is quite similar to sessionid (at least from my knowledge).
So, here's my question, is it possible to use Oauth2.0 to completely replace session? I.e., even people are using the website designed by me (NOT third party website) to access my own server? So that I have a unified authorization framework for user accesses both from my own website and any thrid party website.
Is there any pros&cons of using session & oauth 2.0?
Lastly, how about mobile app? I know for third party mobile app, they normally use oauth to access the server (many websites provides oauth api). How about if I am going to write my own app for my own server (NOT third party)? Does Oauth 2.0 apply here too?
To summarize, my question is actually is, is Oauth 2.0 universal that can be used in all kinds of user authorization control situations from all kinds of devices?
Thank you very much.
Though both are short-living entities, session IDs and OAuth tokens are fundamentally different and used for distinct scenarios. A session is used to identify a user of a web application, thus related to the end user. An OAuth token is used to grant access to a third-party service to access a limited set of protected user resources (e.g. read user contact information or send a mail from the user account). Though the token refers to the granter (i.e. end user authorized the grant), the token related more to the third-party application.
To give you an analogous example: imagine that you have a safe at your bank (i.e. your protected resource). The session is your id for the bank: give it to someone else and he will be you, he can get everything from your safe. On the other hand, a token is a limited authorization to someone else to your safe: e.g. your approval that he can get 10$ from your safe while a security guard is watching.
As a summary, sessions and tokens are not interchangable.
I'd like to secure access to resources in my web application, so I authenticate my users using the standard mechanisms and use server-side sessions to preserve the authenticated state.
I'd like to deploy across multiple systems in a load balanced configuration, but I don't want to start synchronising session state across my infrastructure. Are there ways (using either spec-driven facilities in Java EE or commonly available libs like Spring Security) of preserving the authentication state of a user without server-side sessions, for example by pushing the required state back out to the client? If so, are there additional risks I need to be aware of?
Update - I am using declarative security as per Java EE webapp specs and authenticating via an LDAP repository.
I'm not aware of a framework solution, but the following does work:
After the user successfully logged in you create a secured token and set it's value as a cookie. The token contains all information required (user ID, creation time, etc.) and is encrypted using some algorithm. So all nodes in your cluster can read the token, decrypt it and identify the user. Then you create a ServletFilter intercepting all requests, examining the token and set corresponding user credentials for e.g. ServletRequest.getRemoteUser() by using an HttpServletRequestWrapper.
One way to solve the problem. But you must take care, self-made security must be well-thought-out.
You can store some kind of token in a cookie after authentication, and manage session attributes yourself. E.g., have a database table whose primary key is the authentication token and stores user session data... Don't forget to implement a job to clean inactive "sessions".
As for what you should be aware of, keep in mind that cookies are something easy to access, steal, delete, disable, etc. The authentication token should be something strong and verifiable (hash a combination of the user ip + browser + rotating salt + some other things you can check for).
It is also wise to divide user authentications in two levels. "Has the cookie" and "just validated the cookie"... Let's say that "has the cookie" is a state that can be there for half an hour (or maybe more) which allows the user to navigate the site. "Just validated" state is for important operations, and should require the user to enter it's credentials again. The timeout for this "just validated state" shouldn't be much longer than a couple of minutes.
Keep in mind that I'm assuming that your site is not holding really sensitive data. For those situations I would recommend something such as two-way SSL authentication with external tokens or security cards plus rotating token devices plus biometrics authentication :D:D:D... I guess you see my point.
Cheers,
You can use an open id server to authentication thus separating your authentication and application logic.