I have an html-based Task Module that interacts with my external service via a REST API. I need to secure these API calls, but because the user who triggers the Task Module may be an anonymous participant in the meeting, I can't use graph authentication.
The best I can do is ensure that the API calls come from the TaskModule that was just created and rely on the authentication of the Bot request to identify the user.
I could add a query parameter to the URL used to launch the html-based Task Module, but query parameters are sent in plain text and often logged on servers.
I could limit the life time of the query parameter, similar to the oAuth flow, but unlike oAuth, my flow requires human interaction between the creation of the "code" and the exchange for a "token" so the life time would need to be longer than I am comfortable with.
I compared the values I get in the Bot "invoke" request for the Task Module with the context object I get back from microsoftTeams.getContext() inside the Task Module itself. I don't see anything that would link the Task Module instance to the specific invoke request.
Ideally, I would like to be able to specify the "subEntityId" to be able to pass an opaque value for the specific instance of the TaskModule and authenticate the REST API calls with this secret. So far I haven't found anything that works.
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.
I have a Spring Boot-application with a public REST-API. The user authentication is handled by Keycloak. Users can use the API to submit jobs, which are then executed periodically as a Spring Batch. Some of these jobs require the user to be notified via eMail after completion.
The application currently does not store any user-related information, except the ID of the user, who submitted the job. My problem is now, that I need the eMail-address belonging to that User-ID to send the job-completion notification. The JWT passed to the API, which contains this information, can't be used at this time, since the job is executed asynchronous in the batch-context.
I came up with 2 possible solutions so far, which both have their own drawbacks in my opinion:
solution 1: extracting the required information from the JWT and persist them in the application's database for later use
drawbacks:
the application should not be concerned with storing user-information; it also shouldn't duplicate data controlled by other applications
the user might change its eMail-address in the primary user-database, without getting noticed by my application
solution 2: requesting user-details as needed by using Keycloak-APIs.
This looks theoretically like a good approach to me. The suggested solutions on SO utilize the Keycloak Admin-API (endpoint /auth/admin/realms/{realm}/users/{user-id}) to fetch user-details. This requires the application to be configured as a "confidential client" with own client-credentials and an enabled service account. What bothers me here: It appears a bit strange to me, that a regular application without any special privileges uses an Admin-API. Also, the users-endpoint is not restricted to users, which have previously given consent to access their data.
Is there a good way to solve this problem?
If job requires an e-mail for its completion, why doesn't it request it as start parameter and just keep it in memory?
This is how I would proceed:
#Controller extracts e-mail from ID token on the end-point from which the user triggers job start
user e-mail is provided among other parameters to the job
job completes sending the e-mail
e-mail is lost, with other job resources
I try to use composer to develop a block-chain web app.
I write the ".acl" file to implement access control, and I also issued different IDs to different participant, then I start the REST server.
The next thing I want to ask is, how can the REST server identify my identity?
Just like, one kind of participant is named "trader", I specify "trader" cannot access function "A" in chaincode, but REST server generate the API of "A", then I write a simple html file and send a POST request to localhost:3000, I can invoke this function directly. I even don't know I access this interface by what kind of identity.
I am confused about this, can some one help me?
Remember how you started the REST server? You had to specify a business network card, and likely it was the card for the admin with all reading and writing rights. Also most likely, you disabled authentication with passport.
With these two elements, of course you can always do anything just by calling any available API function.
You can refer to the passport authentication instructions for composer-rest-server to implement your authentication scheme.
You should code the rules for what is allowed for certain groups (such as "patients", "doctors", "payers") in the ACL permission files. Refer to the section "Granting Network Access Control" in https://hyperledger.github.io/composer/latest/reference/acl_language, which contains some pretty similar examples.
Illicit API calls would then simply fail if attempted by the wrong entity.
I'm using Lambda functions, executed via API Gateway using a Cognito User Pool Authorizer.
I know I can get the "standard" user attributes (like sub, email, cognito:username, etc.) from event.requestContext.authorizer.claims.
But this does not include custom user attributes (like custom:myAttribute).
I know I can get them via adminGetUser, and this works, but I wonder whether I can save this call and somehow get those custom attributes automatically in the event?
Have you already looked at this doc for custom claims?
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html.
You will need to define context in following manner for custom attributes:
{
"context" : {
"role" : "$context.authorizer.claims['custom:myAttribute']"
}
}
After you add a custom attribute to a Cognito user pool and assign a value to it for a user there are a couple of reasons why it won't appear in the requestContext.authorizer.claims collection.
The first and most obvious is that you need to make the custom attribute readable via the app client you use to generate the ID token you are authenticating with. If you are using the AWS console this is done by navigating to App Clients -> Show Details -> Set attribute read and write permissions then tick the attribute(s) you want to make visible to your Lambda.
The second reason for your attribute not appearing, even if you have completed the first step, is that the user's claims are encoded in the ID token you generate. This means that if you're using an ID token created before making the attribute(s) readable you still won't see them. The solution to this is to just generate a new ID token for your user at which point you should see the attributes in your Lambda's request context.
I'm currently working on a iphone/android project where the mobile talk ta java backend server through REST API calls.
The Java backend is done using Spring and its Authentication system (with a JSESSION ID token)
I'm not an expert in security but I can see that if not implemented correctly there could be quite a lot of issues.
One of my biggest concern would be user creation for example.
When the app creates a user it simply makes a POST request to (url.com/rest/create)
How can I avoid, server side, that a malicious user puts this url in a loop and create thousands of users ?
What are common best practices to secure API calls ?
Is the Spring Authentication token enough ?
Thank you!
It's not really possible to prevent a client from making many calls to your server. A malicious user can create a script or application firing requests to your server.
The solution is to authenticate and authorize the calls to the server. You give certain users (for example administrators) the privilege to create users. You trust those users to behave in a correct manner. You have your users authenticate before they call the APIs on your server. Then, on the server side your check who the user is and what he/she is allowed to do.
If you are still concerned about privileged users not behaving, you can assign quota to each user on the actions they are allowed to perform.
The hightech solution (with as much framework fuctions as possible) would be
first: have a created-by and created-date field at the entity you want to protect (I recommend to use Spring-Data-JPA Auditing for that).
second: create a custom spring method (or web) expression method that is able to check how many items the current user has created in the (for example) last 10minutes and if this are more then (for examle) 20, then return false (or make them parameters of the method).
Then you can protect your method (or url) with that expression (#PreAuthorize("createsNotExeced(10, 20)"))
But this is the high tech solution - it would be quite intresstion implementing them when one wants to learn spring security. (and you would need to add some caching, but this is also a Spring feature).
The lowtech solution would be: put an list of timestamp in the users session, and add an new item to that array whenever the user creates an new item. When the last (for example) 20 timestamp enties are within the last (for example) 10 minutes, then throw an TooMuchHeavyUseRuntimeException or somthing else.