I have an multitenant application that has a lot of request scoped services, where I look at the origin to see which tenant we're talking about, and which database filters to use, etc. This works fine as long as there is a request, but now I want to run a script for each of the tenants.
What I would like to do is loop through all the tenants, initialize a request scope for each tenant and run whatever needs to be run. How do I do this?
I am in the Nest context (a module's onApplicationBootstrap, to be specific), so I do have access to DI, just not the dependencies that depend on the request scope.
I found this post: Nestjs call request scoped service without request
But it leaves me with some questions:
how do I get a hold of NestApplication
it looks like the request is globally registered to the scope, doesn't that mean that after the loop is finished, the application still thinks it's in that request scope?
Related
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
I had a node app hosted as an azure web app on Linux environment. The node service handles events requests as a GET method. The application was working fine and all of a sudden since last 2 days it started throwing 431 error.
there was another similar question posted link but this is not the case here. I do not have AAD enabled
have also verified below areas
no change in the node app
no change on the client side sending the get request
no explicit headers are sent. this was verified by making simple postman calls as well
what could have gone wrong here? any help?
Is it only happening for certain users? When I've seen this in the past, it was because we kept user role & state in the token (which generally does get passed in a header) and for some "test" users that had access to absolutely everything, that token was too large and we had a 431. For pretty much any other user things were fine.
Our fix was to use a key-value store (could be SQL, CosmosDB, etc.) and the user token was now an ID that mapped to the value in the data store, and the role & state info was moved there.
currently I develop a backend based on the microservice architecture.
Unfortunately, I have a problem how to realize the authorization.
So let me explaine my system - there are the following services:
OAuth 2.0 Service (issuing JWT)
Group Service
Some Ressource Services (e.g. ToDos Service)
Every user is in one or many groups.
Each resource (like a ToDo list) also belongs to a group.
That means if some user creates a todo list, that list gets stored in the name of the group.
Szenario:
User A is in group A
User B is in group A and B
User C is in group C
User A creats a ToDo list in group A.
User B modifies this ToDo list (he is allowed to do this since he is also in group A)
User C also tries to modify this ToDo list, but he shouldn't allowed to do this since he is only in group C.
Has any body a great idea how I could realize this in a microservice architecture and keep the dependencies between the services on a minimum?
Certainly, I could ask on every request the Group Service if the user is in the group to which the resource belongs to. But so I get a really hard dependency between the Resource Services and the existence of a Group Service - I like to avoid this dependency.
Another option would be to store all groups, to which the user belongs to, in the access token. But with this option the client has to ask every time the OAuth Service for a new token when the user gets a member of a new group.
So is there any other option how I could realize this szenario?
So, you have three domains:
Authentication: responsible for identifying the user
Authorization: responsible for restricting access to resources
Todos: your core domain
You have done well identifying three bounded contexts, one for each domain and implemented in three microservices (MS). You are conforming to the best practices regarding DDD.
No, your question is how could you integrate those three microservices in such a way that the system is resilient, i.e. its microservices continue to work even if some of the other microservices fail.
You have two options regarding integration (communication between microservices):
Synchronous communication: every time the Todos MS receive a request, it queries the Authorization MS to check if the user is permitted to do what it wants. This has the advantage that is simple to implement but it has the disadvantage that is susceptible to cascade failure: if the Authorization MS fails then this MS also fails. So, this option is not good for you.
Asynchronous communication: somehow in the background, there is some data that is replicated from the Authorization MS to the Todos MS. You have at least two options for this replication to be done: a) in cron or scheduled tasks or similar and b) using a event driven architecture. This has the advantage that provides more resilience but it has the disadvantage that is more complex, harder to implement. This option seems to fit your need.
Further reading:
Building microservices
I would suggest to put the authorisation handling into a API gateway. When there is an incoming request the following steps are executed
1.The API gateway hits the OAuth server to get a transparent token which contains the access roles and groups of the user
2.The API gateway then calls the to do services with the access token , which the to do services use to decide if a particular user is authorised.
The advantage of this integration pattern is that the individual services don’t have to call the group service to get the roles.
I'm learning about RESTful interfaces. To update a server resource, say for a Contact with (id = 1) I'd PUT it:
PUT /contact/1
Now suppose the current user belongs to Organization 1, which owns Contact 1. There is also Organization 2, with Contact 2. The current user doesn't belong to Org 2 and has no rights to it. If the user hacks the web page (using Firebug for Mozilla or the "F12 debugger" for MSIE) and changes the web page request to point at /contact/2, the browser will merrily submit the request.
My server must protect against such cross-organization attacks. In my current web site design, once the user logs in I store a data object in the session (I'm using Tomcat/Java). That object stores which organization the user belongs to. Safety checking code compares the organization for the passed-back PUT request against the organization the user belongs to and sees if the passed-back data belongs to the user's organization. On detection of a hack (the user for org 1 is trying to modify contact 2, belonging to org 2) an error is returned to the browser.
I understand that REST is supposed to be stateless, but I'm currently using some state. Yet, if I pass the user information into the web page I think that this, too, can be hacked through Firebug, et.al.
How to achieve this safety without invoking server state?
Thanks,
Jerome.
RESTful services are usually stateless.
This means that every request has to be authenticated with an apikey or something else.
So the request will be /path?apikey=MYKEY and the server will handle the rights of that apikey.
By the way I've also tried stateful rest services, and the server is able to understand the session by a cookie initialized during the login (but that's not really RESTful).
If you want to try them with curl do something like:
curl -c cookie.txt -d "user=username&password=pass" "my.login.path"
curl -b cookie.txt "do.something"
I have a Microsoft Dynamics CRM implementation (either 2010 or 2011 in not 100% sure). This CRM system needs to call our internal service framework services from plug ins.
In order to call the service framework we use an API with a login method that goes to an STS and gets a security token. This is per user to authenticate and get that users claims. The login call returns an IPrincipal object that we put on the Thread.CurrentPrincipal property and from then on we can call services with our framework and the user is authenticated for each call because of the principal on the executing thread.
In an asp.net website we usually log the user in and immediately go to the STS to get a token, then cache that token for the user in session because the login is not something we want to do every time we want to call a service.
How would I do this with a CRM plugin. Do I have access to a per user session store? I noticed IServiceProvider is passed in as a parameter, can I add services to this container and solve this problem in a service with a thread safe dictionary of some kind? I know very little about CRM development and Im even wondering if a plugin is the right way to do this?
The plugin is created and cleaned on a regular basis, you wouldn't be able to store anything for any period of time (or at least store it and rely on it being there).
You could potentially store this in a custom entity though if that is something that is possible?
e.g.
- Plugin is called for x event
Get CallingUser from Plugin
Search for MyCustomSTS entity for the User
See if Token exists and/or has expired
If you have the token - hooray
If not, run off and grab one
This may, of course, take longer than reauthenticating each time!
Is the token you are fetching for individual users or for the service account?
Ideally you should write your plugin to be stateless.
Write a Plug-In
For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. Also, multiple system threads could execute the plug-in at the same time. All per invocation state information is stored in the context, so you should not use global variables or attempt to store any data in member variables for use during the next plug-in invocation unless that data was obtained from the configuration parameter provided to the constructor. Changes to a plug-ins registration will cause the plug-in to be re-initialized.
If you are fetching a token for individual users you could save that in CRM somewhere but that approach has a number of problems as glosrob suggests. In this case its probably just best to authenticate every time.
If its for the service account, you could go against the recommendations of Microsoft and cache the token in memory. Logically as long as your write your code to be happy with randomly loosing and having to reacquire its token you should be okay.
I agree with people who says that each time authentication is better solution, but if you need storage for tokens, you can create custom CRM entity and write logic which will work with tokens stored in CRM from plugins.