NestJs authorize/validate user owns resource - nestjs

What is the standard way of validating/authorizing that a user has access to a resource?
For example: a user can PUT comment/:id to update a comment, and I want to check if the user is allowed to.
Guards aren't ideal because they run before any validation and I need to access the comment id.
I've also tried a custom Param pipe but I'm struggling to access the request execution context from it to get the user.
Finally I could also just put the logic in the controller.
This seems like a pretty common use case so I was wondering: how does this typically get solved?

A common practice is to use OAuth 2 framework. Each valid user will have associated accesstoken that will be validated in the server before the user is allowed to access resource.
For NestJs Framework, you can checkout the official documentation on how to achieve this. https://docs.nestjs.com/security/authorization

Related

Suggestion required on how to implement a better permission system

I have a user permission system in place where i have a set of permissions within the database, for example
id
Permission
1
POST:CreateBooking
2
GET:AllBookings
And i have another table (junction table) where i put dependent permissions such as
if i want to create a Booking, i need to fetch Package details and so POST:CreateBooking requires the user to also have GET:AllPackages permission.
There's a template system in place as well, where the users can group multiple permissions together and once that template is assigned to any employee, that employee will get THAT set of permissions and it's dependent permissions.
What my nodejs system does is that when user logs in, it fetches all permissions from DB and puts it in a redis set from where on each request, the permission is checked against user id.
Is there any tool from where i can do exactly this but in an intuitive and better way?
I tried keycloak but i don't know how to cover my needs mentioned above.
Thank you
if I'm understanding correctly and trying to generify your scenario, you have a classical situation where:
You have groups which can have multiple permissions assigned;
groups can be created dinamically;
each permission correspond to a specific functionality.
So, implementing the OIDC (Open Id Connect) protocol might fit you needs. As you suggested youself you might be interested in a OpenID provider (do not reinvent the wheel) keycloak is good, you can give a look also to Vault Hashicorp.
So assuming that your backend have an already existing framework to handle security and permissions (eg. Spring Security) you can produce JWT token with the OpenId provider and check throught PreAuthorize claims (permissions) inside the token.
At the end your security layer it's just an annotation you need to insert before your method controller or before you class controller.
Behind the scenes, instead, this is what will happen:
Your user connect to your app;
User insert username and password -> the Open Id provider gives you a JWT
Your Front End app everytime it make a REST req will send also the JWT
The back end controller method called it's under authorization
Given the public keys of the OpenId provider, the validity of the token it's enstablished
If the specific permission claim it's found inside the token, the request can be elaborated else a 403 Forbidden it's returned.
OIDC - as the conceptual model/backdrop to any tool of choice, is certainly a popular/good choice, but as long as you're willing to deal with an element of complexity - the understanding required to implement an OIDC arrangement (- think of it as a possible investment - effort up front with hopefully the rewards tricking-in over time); e.g. OIDC is an ideal choice for supporting SSO (Single Sign On), especially when it comes to supporting/allowing for authentication/login via providers such as Facebook, LinkedIn & Google, etc (- as well as more Corporate OPs (OIDC Providers) including AAD/Azure AD).
Try to first step-back, and consider the possible bigger/future picture, before selecting a tool based upon only your starting/current requirements.

User Info from JWT Kogito

I understand the mechanism of OIDC in Kogito with the help of process-usertasks-with-security-oidc-quarkus example.
However, I have a question about user information. In the given example, the approved field is filled by a Query string. Is there any way to get user information in Kogito? If it doesn't have that feature, can it reflect from header to service?
The integration with the security context inside the Kogito app is something that is on the radar, see https://issues.redhat.com/browse/KOGITO-6162. That would ignore the query string and use the authenticated user. Perhaps, for now, you could create your own endpoint to retrieve the authenticated information as needed and mimic the same API call that is done in the generated endpoint.
I figure out a temporary fix that problem with help of written Custom Service when using Kogito with Quarkus.
https://quarkus.io/guides/security-jwt
JWT Injection can call from the Service layer when used with Kogito.
It is also possible to propagate user identity to other workflow items with internally tagged process variables.

Deployd: How to implement dpd-passport and securely authenticate

Let me start by saying I really like Deployd. I want to use it in production, but I want to incorporate OAuth and social logins, so I installed the dpd-passport module. It works great, except for two little (big) problems:
When a user signs in via an OAuth provider (e.g. Facebook, Twitter, Github) a new user record is created...but if the same user clears their cookies or uses a different browser to log in, a new user record is created.
If I do something clever (read: hacky) and assign users with social logins an ID based on the socialAccount and socialAccountId (something unique but constant for each social account), someone could use the standard method of user creation to spoof a user by making a POST request to the /users endpoint if they knew that user's socialAccount and socialAccountId.
My question is: How can I A) prevent #1 from occurring, or B) disable the standard method of user creation without also preventing OAuth user creation?
Has anyone ever successfully used Deployd and dpd-passport in production? If so, I want to speak with you...
Thanks in advance!
First of all, I think you haven't added the custom fields per the docs.
https://www.npmjs.com/package/dpd-passport#requirements
I hadn't either, and observed the new user feature (because it couldn't lookup the response from the auth service to find the user from before). Adding these fields fixed it.
Also, there is a google group here:
https://groups.google.com/forum/#!forum/deployd-users
Hope that helps.

Implement API key solution for Sail.js

I want to make an option such that I can issue 3rd part developers access to my data and to do so, similar to the following: https://docs.sharedcount.com/, I want to create a system wherein those developers are provided an API key for which the consumption count can be monitored
Came through Waterlock but does not look like it has this feature: http://waterlock.ninja/
Curious, what would be the best approach to implement API keywords for a Sail.js app?
Sails makes this incredibly easy by use of policies. When a user signs up, assign them an API key, and then create a policy that checks the params for a valid API key -- i.e. req.param('APIKey') -- and deny access if one is not found.

Simulate signin/login using Symfony/sfDoctrineGuardPlugin

In a situation, where the user is authenticated on another application (like oAuth or a custom security implementation), how can we simulate login?
What we intend to achieve is:
- use the user identifier key to check if the user exists
- if the user exists, set-up the session for the user
- basically, setup the attribute holder
- assign the user object, so that it is available thru getUser() method
So we are looking at signing-in programatically!
Any light on how do it in the simplest way?
if using sfDoctrineGuardPlugin, i'd do something like:
Redirect user to 3rd part oAuth provider
On success, user returns to you, either create them a new sfGuardUser object, or retrieve the appropriate one (you may need to adapt the schema to have somewhere to store extra oAuth data).
Call myUser()->signIn($user), where $user in the previously retrieved sfGuardUser object - eg: I use this in register actions to log people in after registration: $this->getUser()->signin($user);

Resources