I need to develop an API using ASP.NET CORE 3.1 for an external company to update some subscription data.
This API is going to be used for a mobile app, and we are using a JWT bearer token to identify the users, so when a user logs in to the mobile app, we create a token and after that, all the methods of the API check the JWT to verify the user logged in. Until this, no problem and everything works just fine.
But we have an agreement with a external company to make some payments in their app, so we need to provide them an API method so everytime someone pays we can update our database. The problem is we have no control over this company app.
My question is, how can we protect that API method so we are sure only the calls from this external company app can get and update our database, but no one else can do it? A simple password?
Using VPN Tunnel it is running securely between to parties as if it was running lan.
strongSwan is a complete IPsec solution providing encryption and authentication to servers and clients.
It can be used to secure communications with remote networks, so that connecting remotely is the same as
connecting locally.
StrongSwan is one of the solutions, many other products can do the same.
https://wiki.strongswan.org/projects/strongswan/wiki/IntroductionTostrongSwan
Related
I have been doing a lot of research into how to authenticate mobile apps with an API - I still feel a bit unsure about which flow & architecture would be better to use in my particular use case.
I think what's confusing me is some of the terminology used.
My use case:
An API & database on one server. Which holds the users & and the users resources.
A web app, which I have built and consumes the API. Hosted on the same server as the API. So it's dogfooding.
A web app, which I have built and consumes the API. Hosted on a different server to the API.
A mobile app, which I have built and consumes the API.
I'd like to be able to authenticate with the API using username & password.
The API will never be opened up for consumption by other 3rd party services except the web app and the mobile app.
Initially I felt like using the Resource Owner Password Credentials Grant flow would be sufficient. However in the docs it states that this flow should be used if "The client is absolutely trusted with the user credentials".
Since both my mobile & web apps will be built by me, I'm assuming they are seen as 1st party clients. Therefore am I right in thinking they are considered to be trusted with the user credentials? As I typically thought that when implementing oAuth, the idea would be to have the authentication server separate from the resource server. Which would allow you to have one authentication server for multiple APIs.
After reading this post: Why the Password Grant is not suitable for modern applications
It threw me off track a bit. But then, is this post talking about using this flow in my use case?
I was also looking at the Implicit Grant Tokens flow. However using this flow I couldn't really see how the user would enter their credentials first?
I also question if any of the oAuth flows is really needed for my use case and I should instead look at other ways of authenticating?
I'm really quite lost with this I would like some direction to go in with how to authenticate users in my particular case.
Thanks in advance!
I'll most likely be using Laravel to house my API and so I do have Passport available to me to implement oAuth
EDIT
From following this oauth article I've found that in all use cases of my app, I end at Password Credentials Grant flow. Would I be correct here?
Not sure how to go about doing this; I'm not looking for B2C, I don't want my users to sign in. I just want my Xamarin app to be able to access an Azure AAD protected API. In other words, I want to authenticate the app itself with the Azure Active Directory, to access an Azure AAD protected API. From what I've found on the internets, service principal to service principal auth is discouraged when using mobile apps and I've not really found a way to do it service to service anyhow.
Any suggestions on how to properly do this? Links with tutorials would be great.
Thanks!
Azure does provide the ability to generate a client ID which you could have sent from your application and checked. Microsoft talk about this in this article. You will want to be careful with how you store this ID in your app as if someone were to steal this they would be able to access your API. Along with that you'd also want to make sure that your connection between your app and server is secured with a pinned SSL certificate so it cannot be man-in-the-middle'd.
Another interesting approach is software attestation where some service checks various aspects of your app to ensure that it is your app. Full disclosure, I work for a company which does this. See Approov. We take a fingerprint of your app and our SAAS checks that this matches at run time. We then issue a token which your app can use to prove that it is the real app.
I have an API with the following method:
https://api.example.com/services/dosomething
I am providing this service to three different mobile apps, each one with hundreds of users. When a user logs in in the mobile app, a call to my API needs to be made.
I know that providing each one of the three mobile apps a different API Key and doing a HTTP Basic Authentication with it is not secure, since the API Key would be unsafely stored in the device an anyone can take it and make bad use of it.
The approach of OAuth2 doesn't work, since I only have information of my three customers, not their hundreds of users.
What is the best approach to secure the calls to my API on mobile?
In your case, your approach with OAuth2 is good: mobile apps (clients) receive delegation from resource owners (your users) to call protected resources on a resource server (your API).
You only have information about your clients because OAuth2 is not dedicated to authentication of your users but authorization of you clients.
The clients are identified with a client ID. In your case and if you want to know which client calls your resource server, then each client should have a dedicated client ID. You may also identify it using other information such as the IP address or a custom header in the requests it sends.
If you want to know who your users are, you should implement the OpenID Connect extension. This extension works on top of an authorization server based on OAuth2.
The authentication of the user is performed by the authorization server. An ID Token is issued with information about the user. The client (or mobile app) does not have to get or store user's credentials.
There is an excellent video where the both protocols are explained (especially from 4:44 to 11:00).
I am developing software that will be used on small system at clients. The software is fetching Google calendar events from whatever Google account the client adds to it. The thing is that Googles API requires an secret key to work. As it is now, the system is working but the key is directly in the code, which means that the end user will be able to see it.
Firstly, is this a problem? I guess that because the key is "secret", there will be bad if a client can see it. Second, if this is bad, how should I do to avoid this? Is it even possible?
I should not be a problem since the key alone is not enough to generate an access token. You also need a refresh token or authorization code for that.
One risk is that, using the key, one of your clients (Alice) builds an OAuth authorization URL and tricks another of your client (Bob) into authorizing Alice's custom application to get calendar data. That problem only occurs if you're using the "installed application" workflow with the "urn:ietf:wg:oauth:2.0:oob" redirect URI.
If you want to avoid this problem, you can decide to host a web service that will handle the authorization for the embedded system. This web service will hold the client secret, and will receive call from your systems to either request authorization from a customer or refresh a token. Of course now you need to secure this web service, but you can probably do that with a customer-specific set of credentials. That way the only thing on the customer's premises are his specific credentials to access the webservice, nothing else.
I recently started a new project using different carefully-chosen technologies, my project is built as follow :
The approach is API-Centric, which means I'm building a website and an iOS app communicating with an API written using Symfony2. I've successfully managed to write my API, and it is perfectly working.
To gain access to the services provided by the API, the main actors (the website users, the iOS app users and the developers) can authenticate theirself in several ways :
Clients can gain access with a login/password couple through the website interface which is communicating directly with the API through AJAX to validate the provided credentials and set a session. So, when someones logs in our website, they have automatically access to the API as well.
Developers can authenticate theirself through the API using HTTP-Basic over SSL, which will as well generate a session and give them access to the services they are authorized to call.
Also, Developers and clients can gain access to the website and the API using their facebook account through the Facebook Connect functionality. This deletes the step where each actor has to create an account on our website.
So basically, the credentials are provided either through HTTP-Basic or using the Facebook Login functionality.
Now that my authentication system is working and that my clients are able to access the website, I would like them to connect to a real-time server when they log in. Like in Facebook or Google+ if you want where the real-time server manages chat and push informations.
In this case i'm using Node.js and the powerfull socket.io library to manage everything that deals with the real-time side.
Of course, the real-time service will need some credentials to authenticate the user since he is authenticated to the Symfony security system with a session but is not authenticated against the real-time server.
A solution I've been thinking about would be to use the PdoSessionStorage in my API (Symfony side) and store all the active sessions in a database such as MySQL or PostgreSQL. Doing so, I would be able to send to my real-time server the session id generated by symfony and check on the database if the session id provided is correct or not. If he is I'll let the user access the services provided by my real-time server and associate his session with an identity.
But I really don;t know if this is a good solution and I would like some more experienced advices on this and on how to deal with this issue.
Note : For some reasons, I cannot implement OAuth even if it could be a solution to solve this issue using a Single Sign On approach.