Found myself opening a couple of functions for access to users with invalid session tokens. The only way I could find to do that is to intercept the request using a bodyParser before Parse gets the request and removing sessionToken from the request.
Now trying to do a better job managing authorization to all functions - My question are:
can I relax the requirement that if a sessionToken is included it must be valid in any other way? Is session token validation done using a default validationHandler that can be replaced or is that done elsewhere?
to control access to cloud functions, is there anything like ACL roles? does cloud function's "validationHandler" accept only param? or can I inspect the user object as well?
Yes. In parse-server you can make sure that the sessions are valid because if you will try to run any CRUD operation with invalid session you will get http 403 error that your session is not valid or expired. You can control on the "Length" of your session by changing the sessionLength property in your parse-server app. The default is 1 year
There is no control access to cloud functions but you can check if a logged in user trigger this function by checking if the request.user is not undefined. Cloud functions can get only params in key-value pairs and those params cannot be Parse Objects. if you want to send ParseObject you can send the objectId of the parse object and then query for it in cloud code to get the full object. You can always access the user context in request.user (only if cloud code was triggered by the user). If you still want to "protect" your cloud code you can check if the calling user have a Role by query the Role DB and check if the user is contained there.
Related
How does a Lambda Authorizer detect if an IAM user has been Disable?
We have a two client servers of Iterable and Punchh. The first one uses a payload of just the base64 token of the username : password while the other server uses the username and password (password is masked).
These 2 servers are pushing (POST method) events down to our API Gateway. To avoid any ,malicious packets being sent down to the gateway, we use an IAM test user (dd_transfer in the example figures below) that can be disbaled once malicious packets are discovered. Thus the IAM test user should now be denied access to the API Gateways where both Punchh and Iterable are pushing their payloads.
When I have an active test user, they are allowed access to the API gateway whenever Punchh or Iterable webhooks push(Post) data. However when that same user is Disabled (password is null) in IAM, that user should not be allowed to access to the gateway. Unfortunately, the 2 external servers are still allowed access once the IAM test user has been deactivated/disabled. I don't want to program and search through a credentials report csv file using boto3 that's encoded to base64. This would expose too much account user info - very risky. Is there another way for the Lambda Authorizer function to determine when an IAM user has been deactivated?
Here are the screen shots below for code, gateway , and servers.
Note that the payloads for the two servers are represented differently. Punchh webhook admin page uses password and username while Iterable webhook admin page uses only the base64 encoded token.
Thanks
Lambda Authorizer Code
API Gateway Method (Note: Post and Get Method Requests are identical)
Lambda Authorizer configuration
Punchh Webhook page
Iterable Webhook Page
I found a safe way to determine whether the dd_transfer user is enabled or not and that is with using the GetLoginProfile API. https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iam.html#IAM.Client.get_login_profile
If there is a valid password for dd_transfer, then a LoginProfile object will be displayed in the response message, a 200 response code is returned, and the access to the API Gateway will be given when the policy is generated (‘Allow’).
However if the password is null because the dd_transfer has been disabled, a NoSuchEntity exception will be returned indicating that the Login Profile for User dd_transfer cannot be found. It’s blunt but at least I don’t have to worry about access being given to allow malicious events to bypass our API Gateway and into S3 buckets.
I have added a try/catch block to gracefully handle the error by calling the generate Policy function passing the ‘Deny’ parameter in order to generate the Deny Access policy.
It’s a lot less work than using the Credential Report API and then BASE 64 decoding each record in the text/csv file to look for dd_transfer’s entry. The csv file doesn’t expose actual raw data like passwords etc but GetLoginProfile takes less to write up. Then in the exception handler, I would make a call to the generate the Deny Policy.
I'm doing some discovery with NetSuite but am struggling to find a way to get the currently logged in user's NetSuite access or id token.
Use case is I want to call an external API (that I'm creating) from SuiteScript. I have decided to use the https module in a User Event Script when a record is created. I want to include the NetSuite access or id token in the Authorization header with this request.
I understand that I can use NetSuite as an OIDC provider which means I can access the public keys for my account via JWKS URL and validate the NetSuite token, verify user role etc. and permit the operation. Therefore securing my external API.
Is this possible?
You can get data on the current User by Using the N/runtime module.
Typescript import and examples of use
I have a problem where the user still can call the API after logout the application by using POSTMAN. There is no problem with the browser side after logged out since I have removed the access token and clear the cookies. But the user still can call the API and get the results using POSTMAN, which means the back-end doesn't invalidate the OAuth token. This may cause security issues if anyone stole the access code.
I have think to apply validation before the API called. I will add a column in the database table which its' value is either login or logout to indicate the current user status. Then, I will fetch this value from database for every API called to do validation. If the value is logout, then the API will return some error message. Is it possible to do by using the spring security?
Before adding, yes it works when I give the entire url like http://localhost:8080/onedrive/oauth2/success/1 in the list of uri in azure uris. I am using code flow to authroize these tokens.
But as per the docs, it should work with me just mentioning the domain name there, like http://localhost:8080. Which it doesn't.
I want to do something like send the user id along with every request for me to keep track of which user I should link this accees token to, and have no idea to do so, if this issue is there. My current application logic is, when my application sends the user details and calls my spring API, I want to handle all these transfer of tokens in the server side, so I want to transfer this userId as my path variable. How do I go about doing this? Has anyone done this, can they explain to me any other different solution?
You can't add custom details to OAuth redirects and it is best practice to always register the full redirect uri.
In terms of tracking the user, after login the token has a user id and you can also get fields such as user name and email - so both the UI and API will know which user each token is for. I can provide further details on mechanics if needed.
The user id in a token is often a generated value, whereas the user id you want to use in API path segments is maybe a user id from your app's back end database - if so you will need to map between token details and database details.
If you provide redirect uri as http://localhost:8080/ then it means you are handling the api response in
/
endpoint and not
/onedrive/oauth2/success/1
To get to know the user to whom you are linking, few ideas which you can use are
1) Use security to obtain the logged in user credentials (Ex: Principal if you're using Spring security in java)
2) After successful authentication, use the user id you have and send one more request to backend and store it database with userid as a key
Using the OktaSignIn widget, I see I can get res.session.token. Can I use this (or some other attribute) in another app -- with the APIKey -- and validate that this is a valid session?
We just want a simple to use auth system and don't want to set up OpenAuth...
Can't seem to find any APIs that do what I need.. but could have missed it of course...
Edit. Basically... our front end uses the OktaSignInWidget... then we want to use this in a Bearer token our API Services layer can validate.
Thanks!
Looks like this will work...
/api/v1/sessions/me
Get id from this.
{"id":"102wtHeHhr4Q4q4rh2Fjy6pGA","userId":"00u9uwkfyfiz3Y7uk0h7",
Then... this can be passed and using the API key...Issue a GET to...
/api/v1/sessions/102wtHeHhr4Q4q4rh2Fjy6pGA
Returns...
Session...
The call to /api/v1/sessions requires the API key -- which is fine.
As you mentioned, you can use the session id to see if the session is still valid on the Okta server by:
Exchanging sessionToken for okta session
After redirecting back to your app, calling /api/v1/sessions/me to get the sessionId
Using that sessionId in the request to /api/v1/sessions/id with an apiToken to see if it's still valid
This will exist as long as the user has not logged out of Okta, but the browser state might be different - for example, the Okta session cookie will normally be deleted when the user's browser closes, while the session might still exist on the server.
Alternatively, to check if the browser session still exists, you could make the validation check on the client side by making the request to /api/v1/sessions/me - the one gotcha is to make sure that CORS is enabled for both the domains your apps are running on so they have permissions to make this request to Okta.
The above methods work, but it does sound like what you should be looking into is Okta's API Access Management (OAuth2) - it was designed for this type of flow (passing Bearer tokens to your API services layer).