I started composer rest server in multi user mode, using github oAuth authentication. I opened one session in chrome and one in firefox (to emulate as two different users) and authenticated using github. Now in one browser I wish to use one network card and in chrome another network card. Now when I import a network card in firefox same is reflected in Chrome as well. Doesn't it defeats purpose of authourisation ? So if one user is using its network card to perform transaction the other user will also be using the same network card as its been set as default for composer rest server. How to deal with scenario ?
The default is set at the REST Client - not the REST server. You're consuming the REST APIs as a client - as the two different blockchain identities (contained in each of your business network cards). Once a client has authenticated to the REST API, that client can add Blockchain identities to a wallet. The wallet is private to that client, and is not accessible to other clients. When a REST client makes a request to the REST server, a Blockchain identity in each clients wallet is used to digitally sign all transactions made by that client (because the identity is set as default, at the time).
The github authentication scheme is a 'delegated' authentication scheme and is using a client application (id and secret) authentication mechanism to enable a client to use the REST APIs and get a token, without needing to authenticate as a user every time.
I had this same problem. Configured the composer rest server with multi user using a jwt strategy, but I was seeing the same wallet (and the same default card) regardless of which user was logged in.
I found that the loopback-component-passport package which largely manages the wallet data was importing my users correctly, but they were all being associated with the same identity because the identity id was taken from the COMPOSER_PROVIDERS config and not the signing in user.
To fix it I modified loopback-component-passport/lib/models/user-identity.js.
Look in the UserIdentity.login method around line 100 where the userIdentity is being populated.
Change:
provider: provider,
to something like
provider: profile.sub,
depending on your payload / user profile.
After that each user will have their own identity registered in your loopback database and each signed in user should have their own wallet.
Related
My backend code usually wraps the client calls and exposes them via an endpoint like this:
import stripe
stripe.key = "API_KEY"
def wrap_create_customer():
return stripe.create_customer()
Clearly, it's possible to just reverse engineer my backend API and start calling it to read customer data, process charges etc. Effectively, Stripe API is exposed via my backend, since the Frontend-Backend connection is public. (Just like all backend starter codes in Stripe tutorials).
How do I secure the client-backend communication?
My frontend is a public, static site. It is not authenticated with the backend. To prevent requests from foreign origin, I am requiring the origin of the request to belong to my web domain.
Q: But if that's the fix, it would imply that validating the origin would be a sufficient condition to identify the real owner of the request. Then why doesn't Stripe let us move our code fully client side?
The only reason for requiring the Stripe Secret key is to authenticate requests. Why not just add allowed origins somewhere in the Stripe dashboard instead of requiring the key?
Q2: Is the whole reason behind backend code, to simply hide the Stripe Live key from public? Even if the backend can be accessed via 'non-secure' endpoints?
Q3: What steps should I undertake to have a secure client <-> backend integration, so that my backend is guaranteed to know that the request was indeed made by the client. (Client is a front-end application).
Typically, (I've never worked with stripe in particular, but with other similar providers) this works as follows:
The frontend includes an SDK which is initialized with a vendorId and maybe some productIds. There's nothing secret about this information. Because even if anybody else knows them, the only thing he can do with it is to buy items from your stripe account.
When a checkout is to be made, the client sends a checkout/{venderId}/{productId} request to the payment provider. Some providers only provide "checkout links", where the customers are redirected to a secure page hosted on the provider's system. This handles all the payment relevant stuff (secure input of credit card, ... you really don't want to know the customers credit card information!)
once the checkout is completed, the payment provider calls a webhook at your backend sending you all the necessary information about the customer (name, purchased item, transaction id, ...)
you process that information at your backend, and store it somewhere. You can make some infomation available to the frontend for instance via the transaction id
the fontend will also get the transaction id from the SDK, so it can query your backend using this transaction id. What information you want/need to expose to the frontend is completely up to you.
Typically, there is absolutely no need to expose any other of your communication between your backend and paymentprovider via API, let alone forward data from the payment provider to the frontend. Especially, if anybody can access your API without authentication. Of course, you would probably need also some administrative API access too, but we agree, that this is certainly protected by some strong authentication.
In order to prevent fraud/abuse (such as Card Testing) of your Stripe account by malicious users, you'll want to protect some of your Stripe-powered endpoints. Stripe does recommend several mitigations, including user authentication, rate limits & captchas. Depending on your application & business, you might need a combination of several of these.
Note that user authentication can be added to static sites using a variety of self-hosted or third-party powered tools. GatsbyJS has a some pretty good documentation of this with multiple examples. Pretty much any pure client technique can be spoofed (such as origin, referrer etc), so those alone would not be sufficient to protect your backend server.
I am new to Azure API Management and will be happy to receive suggestion and advise on my implementation.
I am developing a B2B Api Channel for 3rd parties to call my services via the API Management (APIM) Gateway. On the APIM developers portal I can onboard new clients and generate API key. My struggle is how best to figure out at the underlying services who is calling?
I have considered add the API Key generated in the APIM to a database which the underlying service will call to authenticate, however, the implementation will be manual and will not be in sync when the 3rd party client goes to APIM and regenerate a new API key.
What I want is a solution that auto syncs authorization and authentication between APIM and the underlying services.
Since API keys can be replaced, you better rely on IDs to identify clients.
You can pass a client ID to a backend in a header: https://stackoverflow.com/a/42277313/2579733
Now how do you correlate APIM's client IDs with your backend's client IDs?
If there are only a few clients, you can probably update that association in your backend's database manually. If you can use the clients's email to connect the APIM client and your backend client, that's even easier (you're done).
If you will need to register many clients and the manual approach is not feasible... One way to do it is with Delegated Authentication:
Delegation allows you to use your existing website for handling developer sign in/sign up and subscription to products, as opposed to using the built-in functionality in the developer portal. It enables your website to own the user data and perform the validation of these steps in a custom way.
I never used it but it seems you can transfer the responsibility of creating new clients to a backend service (developed by you).
This way you have access to client emails, you generate IDs and can store the ID relationship in the backend as necessary.
I am going to implement security (using Identity Server 4). I have mobile application (front end) and few microservices (back end).
General scenario is that User_John calls Service_A_API using User-JWT token (obtained with Device flow). In order for Service_A to complete request, it has to access some data from Service_B. Service_A is calling Service_B using Server2Server-JWT token (obtained with Client credentials flow).
Server2Server-JWT is "Full access" token, allowing Service_A to do operations on any user on Service_B (e.g. it can delete user's order, update user's money balance, etc.)
Concerns that I have:
Is it correct to assume that Server2Server-JWT can have some long lifetime (e.g. 10-20 minutes) and it can be used for many requests originated from many different users?
Assuming Service_A and B are hosted in AWS (Dockers), is the Server2Server-JWT secure in those service's memory? What if (and how) the Server2Server-JWT get stolen?
Should Service_A request new Server2Server-JWT token for every user to call Service_B (and e.g. store this UserId in Claims)? Or is it safe to assume that Server2Server-JWT is safe in memory, and can be reused for any user request within the lifetime span of the full access Server2Server-JWT token?
Is Hybrid flow an answer to create a Server-to-server token on behalf of a user? Or is it something else?
My source of info are:
http://docs.identityserver.io/en/latest/topics/grant_types.html
https://www.pluralsight.com/courses/asp-dotnet-core-oauth2-openid-connect-securing
I definitely can answer the last question and only try with the rest.
Hybrid is a kind of interactive flow where one app has both client and server parts. Interactive means that a user goes through the IdP's portal to get authenticated.
Mobile apps usually run Authorization Code authorization flow with PKCE extension which all together behave pretty similar to hybrid where the "client" is a mobile browser and the "server" is the app itself.
No place for an API. But... you can look into the Extension Grant docs. Allows to implement Service Credentials on behalf of a user, exactly what you want, but... probably you don't need that with AWS.
They offer Network firewalls built into Amazon VPC, and web application firewall capabilities in AWS WAF to create private networks, and control access to your instances and applications. Together with "Customer-controlled encryption in transit with TLS across all services" that might be more than enough. The decision is yours.
I was reading this pretty cool article this morning:
https://medium.com/#CazChurchUk/developing-multi-user-application-using-the-hyperledger-composer-rest-server-b3b88e857ccc
I am interested in the Rest Server features but I have a couple of questions on it:
How does the Rest Server knows which wallet to use for a specific logged-in client?
How to create channels and join peers from/using the Rest Server?
Thanks hackers!
Once a REST client (where the wallet is) has authenticated to the REST Server, that client can add Blockchain identities (one or more) to its own REST client wallet. The wallet is private to that client, and is not accessible to other clients. When a client makes a request to the REST server, a Blockchain identity in the clients wallet is used to digitally sign all transactions made by that client (and the REST server knows who that is on the business network as that identity is mapped to a participant).
Please note that this feature requires that clients trust the REST server. This trust is required because this feature requires that the REST server stores the clients Blockchain identities as part of the card. Therefore, it is strongly recommended that clients only use REST servers that are managed by a trusted party, such as an administrator within their organization.
All information regarding authenticated users and their wallets (containing each users business network cards when multiple user mode is enabled) is persisted in a LoopBack data source by using a LoopBack connector. You would normally set up a persistent store such as MongoDB and the REST server would use a Loopback adapter to access the MOngoDB store. REST clients that have authenticated via a strategy will normally get an access token (once they authenticate) and which is stored locally (such as in the browser for OAUTH2)
Channels and Peers (which come from Hyperledger Fabric) are configured in connection profiles (connection.json file) which are part of the business network cards built for a participant of the business network. The REST server itself doesn't 'join peers or channels' it knows about it because it is started with a business network card (and the definition of the channel and peers are known to the REST server that discovers the business network to which it relates). Obviously you can stand up many REST server instances to serve the different 'living' business networks deployed (on whatever channels (ledgers) or peers defined in the profile) in an organisation.
I have issued new participant id using Post operation of /system/identities/issue and got the card file having connection json and enrollment id and secret. Now how to generate certificate using that enrollment id and secret using the already created rest api by comopser-rest-server.
As you have found out, the Identity Issue results in a .card file (an archive containing the Connection, enrollment ID and Secret) The Secret is a one time secret and the first time the card is used the Certificates are downloaded and stored locally. After this the Secret is not valid. This works the same way for CLI, Playground and REST API.
For CLI and Playground the cards (and certificates) are stored in under the home directory of the logged in user ~/.composer/ .
For the REST server, you need to run the REST server in Multiuser mode and then there are some new endpoints under /wallet e.g. /wallet/import. The REST server stores the Cards (and certificates) in these Wallets. This is described in this document REST Server Multiuser.
A couple of additional notes: To run in Multiuser mode you also need to enable Authentication for the REST Server. When you stop the REST server the Wallets will be lost unless you persist a datastore for the REST server.
This parent doc has all the information for the REST server. REST Server Parent Doc