I'm a bit confused about the role of user_id when creating a new "client" for Laravel/Passport.
I'm using the Authorization Code workflow, where a 3rd party app will access data from my app after the user authorizes it.
From what I understand, this 3rd party app is the "client" and has no reason to be associated with a specific user, as several different users are likely to use it. Am I missing something?
you are right in the case of authorization flow you won't be using it and probably should be on null, because the authorization flow represents a user giving permission to a client to use its data, now remember there is password grants flow, this flow may be used with only one client (the one you have for default on passport:install command) or you can define a more complex structure where the user is represented by a client and so you will need as many clients as users this is rare as it would mean that each user represents an app but depending on the kind of app or service it may be needed this way.
Also there is the client management scenario. As was mentioned before there are use cases where a user could be an "administrator" to that client and so update values or revoke access, etc.
https://github.com/laravel/passport/issues/600.
Related
I have API backend and it will be consumed by different consumers like our own company website and even other website can use our API with certain quota/limitation and for this scope management we will be using express-gateway(eg), however this is not the only reason I am using express-gateway(eg). Now coming to my problem/miss-understanding, for our own website we can create api-key and user credentials using eg command. But for the other user who wishes to use our api, I don’t want them to contact me for this integration, rather they should be able to create a user credentials and API key themselves using some facility (let us call it key management) provided by us. Here I am stuck how to give a web platform or any other mechanism where a user can create account and then create api-key for their own website. I was thinking to extend the express-gateway app itself and create page where a website owner can fill the form with various input field that will serve as parameter for eg command and I can trigger eg command in node console and create credentials and save it in redis database and then fetch those information to show it to user as their use rid and api-key. But I want to know the best way how others are doing, like how google, twitter and many more are allowing to create api-key, delete key and regenerate the api-key on compromise. Some suggestion would be to use third party tool to manage user-credentials, I will have little inertia to accept that, even if I do so how will I hook those third-party solution to my express-gateway.
In general, API gateways and authentication servers are independent, or at least loosely-coupled. The typical workflow is:
A user browses to the Create Account page for a service.
The user creates an account with the authentication server
The user makes a request through the API gateway
The API gateway checks with the authentication server whether the operation is allowed, discarding it if the user is not authorized to perform the requested action
The API gateway dispatches the request to the appropriate server
The receiving server checks whether the user is permitted to perform the action (in case the API gateway has been compromised)
Express Gateway includes its own authentication server for convenience, but the steps are basically the same. The difference is that one uses the Express Gateway Admin API to create the user and credentials rather than going to a different server.
Note that Express Gateway and its default account database (reddis) are not persistent out of the box.
Is there any way to login other users account for admin user ?
Currently authentication based on Meteor Accounts
I saw this post but didn't working at all now.
The feature is important for us because when user have problem in system then admin need to see it this by simulating user account.
Thanks in advance.
It seems you want to impersonate a user. This means that you want to have Meteor.userId (or this.userId depending on context) reflect the _id of a specific user both on the client and the server.
afaict the only way to do this is to login as the user. Presumably you don't want to ask the user for their password so you have a couple of choices:
Save their existing password, replace it (temporarily) with a password of your choosing, then after you're done impersonating their account, restore their existing password.
You probably don't want to ask the user for their password and you don't need to. All you need to do is set aside Meteor.user.findOne(userId).services.password.bcrypt, then reset the password to your temporary value, then restore the original bcrypt value later.
The downside is that the original user would not be able to login while you are logged-in. Plus it's really hacky.
Extend Meteor's Accounts package to provide impersonation capability in a more elegant manner.
You might also look at validateLoginAttempt. The docs are unclear as to whether a failed login attempt could be overridden with a successful one but if it could then that would provide another pathway to solve your problem.
Instead of logging in as the users, which requires their password and which is a total no-no, you may use rather alanning:roles and allow the admin to assign the role of any user in order to draw views based the user's role.
This requires a well designed role system.
As a plus you could then at least load the documents associated with the user who you want to support.
This requires a well designed document and data model.
But generally spoken you should rather focus on writing good tests (test driven development) for components as unit tests, integration tests and UI tests.
This will reduce the need to manually view the app as an end user a lot.
The most common end user problems can be reduced by creating a good knowledge base like a wiki or video tutorials.
Even if then an error occurs in the end user side, I would rather try to implement a well designed error log that allows users automatically create tickets on error which also include the error stack.
All the above methods are to be favored before logging in AS THE USER.
As #Jankpunkt has already mentioned alanning-roles I can add something you can use without installing any external package.
Just keep a type key in the profile object of the users collection. Then define some types like 1 for super-admin, 2 for admin, 3 for general etc. Then check the authorisation of particular action by checking the value of user.profile.type key.
Caveats: Make sure you are checking the type in server side. By default profile field is writable from the client end, so if you are putting type field in the profile object make sure that you are not allowing users to modify users collection in the client end.
Here is how to restrict client end update in users collection:
Meteor.users.deny({
update() { return true; }
});
Read more on roles and permissions here:
https://guide.meteor.com/accounts.html#roles-and-permissions
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.
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.