Organization on database with userId field in a microservice archecture - security

I have a question on micro-service architecture. example I have :
An authorization and authentication server which provide JWT (Keycloak for exemple)
2 micro service which communicate between them through REST.
1 micro service is a user service which create a new user in my database on each new user from the Keycloak (may be tomorrow we have Google or Github, it's important to take this in mind). When I'm creating a user I store his subject from claim in a specific field.
1 micro service which store the creatorId, the updateById for blog post for exemple.
Is it better to store in my creatorId and updatedById the subject (Like this I don't need to ask to my user service to identify who is a creator) or to store the userId from my user service and everytime call from my post-service which is the user that made the request (So I made Everytime a rest request to get the user which send the request by passing the JWT token to the user service).
IMO, sending Everytime a rest request will increase the load on the user service but a subject id for a different user can be the same for Google, Github and Keycloak.

I would do the following, so that you can move to a different Authorization Server (Google / Github) in future without too much impact:
User Service creates a row in its Users Table for each new user, with a database surrogate key as the main user id
This user id is saved to your creatorId / updateById fields
Meanwhile the OAuth Id / Sub claim is a column in the Users Table, but is not the main user identifier from business logic
The Posts Service can avoid calling the User Service on every single request if you cache claims in the Posts Service. Some resources of mine might give you some ideas that you can apply to your own solution:
User Management Blog Post
Claims Caching Blog Post
Claims Caching Code

Related

Can I create a quickbooks invoice on behalf of another user, in their account?

I am following Intuit's oAuth authentication guide in order to log users in through Quickbooks and get access/refresh tokens in order to make API calls. We make API calls in node through the node-quickbooks SDK.
I can successfully log users in through Quickbooks and exchange codes I receive for access and refresh tokens, and I can even make API calls to create invoices successfully.
The problem is, even when I use the tokens of the user I've authenticated to make API calls, the invoice is created in our Quickbooks company instead of theirs.
Is it possible to create invoices in the Quickbooks account of the other user? If not, what's the point of getting access and refresh tokens for them in the first place? For what it's worth, this is all being done in the Quickbooks developer sandbox (but with two separate accounts).
I'm quite confused as to what the methodology is supposed to be here, and any guidance would be very much appreciated -- or even just a reassurance that this is possible.
Thank you!
The QuickBooks instance that's acted on is determined by the Realm ID parameter. The Realm ID is captured when a QuickBooks Online account is selected during the authorization flow.
If we could call your Quickbooks company "Company A" and the one you're trying to create invoices in "Company B", I'd say it sounds like Company A's Realm ID is being logged and passed in subsequent requests instead of Company B's. This could be caused by things by hard-coding Company A's Realm ID and using that for the create invoices requests, selecting the wrong account during the authorization process, or something trickier like a bug in the SDK you're using.
I'd start by getting Company A and B's Company ID, which is what Intuit calls the Realm ID when you access it from the UI. You can do that while logged into a sandbox or production account by pressing Ctrl + Alt + ? in Windows or Control + Option + ? in macOS. Then you can verify the correct Realm ID is being used in the create invoice requests.
If the requests are using the value captured during authentication (as they should be), then you can —in the SDK code— log the Realm ID that's being captured during authorization and verify it's the right one for the company you selected during the OAuth flow.

how to create a survey app only allow the invited person visit only in a secure way

I have one Node.js app and database is MSSQL. I have implement the basic functionality like register, login and others like adding users. The authentication of the api is using JWT, so when a user login, he will receive a token saved on the cookie, just like normal app.
I'm going to add a new survey functionality to the app. With the survey, it does not require user login and does not ask to create a new user account, but only the person receive the invitation link can visit. What I current save on the survey main table is the email address and person name going to receive the survey and one auto generated UUID. The survey link may be /survey/UUID.
How should I do it and how to secure the survey form?
What I was thinking is to create a new token for each survey use only and attchecd with the invitation link, and then validate that token. But because it does not ask the login, I cannot validate the token with email. Should I need a Recaptcha only? Or I need to the login here, or at least need to the user confirm his email address so the token can be verify?
You could use id (primary key) AUTO increment on the main table, and 10-15 char as password. you generate token based on your format such as url/id+password. Id is always unique so its guarantee that each user will have their own token.

Session between REST calls with node.js for mobile

I have to do registration for a mobile app with node.js (express.js) backend. The registration process involves sevaral steps:
1. provide email
2. verify email
3. provide personal details
4. upload photo
For each of these steps there should be a separate call to the server API ( possibly through REST ).
How to keep the session so that the server knows that the consecutive calls come from the same client ? This is a mobile app so cookie based session won't work I think. Could you guide me somehow ? Is using a JWT token the right way to go ?
I'm not an expert but...
So here you need to firstly answear a question:
How much time does user have to create such account? For example, if you won't store information that user had started to create account and server restarted ( for whatever reason. eg error ), you will lose this info. So it would be worth to store this in some db.
You can use redis, mongodb, some sql db or just system files (not recommended ) it's up to you.
Assuming you want to persist such info, you can create REST endpoints.
So for example, you can have entry in MongoDB (which basically stores JSON structures).
NewAccount { id: <unique_id> , email, info, images }
So each endpoint you create will set info in this MongoDB entry.
Example:
1) POST /user/create -> this would create entry in MongodDB
2) PUT /user/create { body: { field: 'email', value: 'p#pp.pl' }}
3) POST /user/create/finish
We have one more question -> how to identify user? You can try to identify it by IP address. If it's mobile app, you have different ways to store info (eg user token) eg:
https://developer.android.com/guide/topics/data/data-storage
As per your step given :
sevaral steps: 1. provide email 2. verify email 3. provide personal details 4. upload photo
1.Register by email and password
Suggestion: You need to ask for email and password.
i) When a user enters the email and password check user exists with email if not then send a verified email and redirect to login.
2. Once User verified. Now user tries to log in.
i) When a user tries to login check email and password is correct or not.
ii) If correct then generate JWT Token on the backend and send back to APP.
ii) Now using JWT Token you can manage the user session on the app.

How to implement server session validation scenario in MobileFirst 8?

I have a problem with the following scenario using MobileFirst HTTP javascript adapters:
let's say the adapters call 2 methods,
login, that calls a back end service which authenticates the user and also returns a customer_id (input: a username and a password).
retrieveData (protected by security-check) that retrieves sensitive data about a customer by calling a back end service (input: customer_id).
How can we make sure that some client that has credentials to authenticate and have access to retrieveData, will request only data that concern him and not be able to send a request sto retrieveData with a different customer_id from his own? (We assume that this client has tempered with the app and has made it send different customer_id's.)
With MobileFirst 7, after login was successful, we would call setActiveUser setting the returned customer_id as an atttribute of active user or we would call WL.Server.getClientRequest().getSession().setAttribute and again set the customer_id. So when a user called retrieveData, we would take his customer_id input and compare it to the customer_id in his session. If it was different, then they would get an error because they requested data that do not belong to them.
Since MobileFirst 8 does not have a session, how can we prevent this scenario from happening?
In 8.0, "Client Registration Data" is the closest thing to a session.
There are a lot of unknowns about your use case, but I will try to describe the expected behavior is most cases:
Assuming your security check extends UserAuthenticationSecurityCheck, as soon as the user succeeds to login, his user id will be registered in the client registration data on the server. This will map the client to the user in a database.
From that point on, on any adapter you can safely check who is the currently logged-in user by using securityContext.getAuthenticatedUser().
If you want to make sure that a client only accesses data it is allowed to, use this getAuthenticatedUser to check against your database that the requested data belongs to it.
If you really need to store extra custom data in the registration context (the closest thing to a session object) there are APIs in the security check to do so. See RegistrationContext.
In v8.0, the client is able to retrieve information from the backend system because it passed the challenge presented to it, and in return received an access token that enables it to access resources that are protected by a scope, which you define. This is how OAuth works more or less.
Have you read the Authentication Concepts tutorial? https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/authentication-and-security/

Easy way to retrieve userId of a User that is not active yet?

I provision a user through the docusign api and the new user is not active yet (status=ActivationSent). Now for whatever reason I want to deprovision this user. The deprovision API requires a userId. My question is finding this userId efficiently.
I tried getting the user information using the endpoint
/accounts/{accountId}/users?email={emailAddress} but it returned a 400 with error code USER_LACKS_MEMBERSHIP.
I saw I can get a list of all users for an account using the end point /accounts/{accountId}/users and then finding the user and userId I'm interested in. Is there a more efficient way to get the userId in this scenario than querying all users?
Also is there a corresponding SOAP call to get all of the users for an account? I can't find it in the SOAP documentation.
To the best of my knowledge, the method that you describe (retrieving a list of all users and then iterating through the list to find the user you want to deprovision) is the only way to find/retrieve the User Id of a user that has userStatus = "Activation Sent". Unfortunately (as you've discovered), the /accounts/{accountId}/users?email={emailAddress} is only successful for 'active' users.
That being said though -- when you provision a User via the REST API (POST /accounts/{accountId}/users), a successful Response should contain the userId for the new user. Perhaps your application can store the userId that's received in the response each time a new user is provisioned, and then you can subsequently use that userId value to deprovision a user if/when necessary.
I'm not very familiar with the SOAP API, but I don't see a "get all Users" operation in the DocuSign SOAP API Guide. I'd expect that type of operation to be part of the "Account Management Service API", but I'm not seeing it there.

Resources