IAM Authorisation for API Gateway Request (AWS / .NET C#) - c#

I'm building a web API to allow some of our systems to raise incidents in our incident management system. I am fronting an AWS API Gateway for this purpose. I want to ensure the API calls are authenticated and require a valid IAM user. I am comfortable with C# / .NET Core, and have read up on using signature v4 to sign the requests. What I can't work out and need help with, is whether the client has to actually sign the requests themselves in the JSON payload being passed to the API Gateway, or whether they can pass the IAM access and secret key only, and then I do the coding to sign the request? I'm concerned that the third party systems won't have the developer knowledge required to sign the requests. They could pass in the IAM user and secret key easily enough, but not sure if they can actually do the signing themselves.

Related

Secure an Azure AP Service hosting an API

I've created an API and deployed to Azure (be patient I'm new to all this). The API will be used by a single daemon app in another organisation. I'm planning to secure this by:
IP White List - this seems to work an to my mind makes the API pretty damn secure.
Client secret create by AAD - is this sufficient?
HTTPs - I've turned this on (Azure APP service TLS blade). However it just seems to work which always makes me suspicious, do I need to link a certificate? Is the encryption being handled behind the scenes?
If it's sufficient or not depends on your scenario. (e.g. is it hipaa / pci compliance?)
I would also add a Azure Key Vault for storing the secrets; WAF (Web Application Firewall) in front of the API + API Gateway (using API Management).
Your point #2 looks useless to me, you'd better request your client to authenticate against your azure Ad and pass the acquired token to your API. this way you'll know who / when called your service.
#3- Azure gives you a SSL certificate, but if you plain to use your custom domain (recommended), you could either generate a certificate using Let's Encrypt or buy from another trusted authority. The encryption happens at rest and in transit, but you could also use your encryption keys for the encryption at rest part.

Using IdentityServer4 as Class Library instead of Hosting Solution

I have been exploring IdentityServer4 for a couple of days. It performs hosting internally generating a connect/token endpoint which internally validates and generates an access token.
Even to call it a discovery URL is needed ultimately requiring a web app template for hosting.
Is it possible to use IdentityServer4 as a library that just allows access tokens to be generated?
**Updated Based on input from Bryan
What I am trying to achieve here is GSMA Compliance that requires both OpenID Connect and OAuth. I need to generate an Access Token as well as Identity_Token. But the caveat here is that IdentityServer4 hosts its internal endpoint where I do have custom endpoints. Also it require http based calling and I do require a sort of library that I can integrate and internally call to generate Access token as well as Identity Token.
** Some more update
We have hosted a custom GSMA compliant Web API Project and have hosted several endpoints as per required by GSMA ultimately validating and sanitizing the request landing on our endpoints. Internally we do require an Access token and Identity Token to be generated and shared back on the callback of the calling party. Currently, I have used an Identity Server template which is MVC based project ultimately requiring us to use at least two ports/project one for our Custom GSMA compliant APIs and one for Identity Server. Calling identity server via URL add a new hop and an HTTP request needs to be sent out to Identity Server whereas I was thinking to use IdentityServer as a class library somewhat allowing me to pass in input parameter and do get an access token/ identity toke.
Upon dissecting server Identity Server project like
Identity Server 4
Identity Mode
Identity Storage
I got the impression that it's very difficult to exact a library out of these projects that can help me generate access token/identity token easily.
IdentityServer4 is an OpenID Connect (and OAuth) identity service -- it's not just about tokens. Those technologies are primarily HTTP-based. Thus IS4 is built on top of ASP.Net Core's web tech. If you just need tokens (JWT, I assume), it's pretty simple to roll your own and use them however you see fit. A few Google searches (or an SO search) will provide you with the code needed to create your own JWTs (for example: https://houseofcat.io/tutorials/csharp/identity/createjwt). Without more information about how you want to use them, I can't elaborate on this answer.

API Design Architechture - Reverse Gateway?

We are building a large web api (200+ calls). After it got so big, we separated it out into multiple smaller api's. This made sense because we had multiple products that the customer might not have purchased.
So we now have an api per product, however, each api needs the same basic architecture - the connection to the database and all of the custom logic for authentication and retrieving tokens needs to be the same for every api. We do not want them to have to get a new token for each api.
We thought about a gateway api, but we are using swashbuckle\swagger and I don't see a way for that to work with the gateway.
The current plan is to make a token api that does all of the token and authentication. The user would call the token api to get a token, and then, when the user calls each of the product apis, those apis would then call the token api to validate the token. Is this good idea? I'm worried about performance of the api when calling another api. We have a mobile app that will be hitting these api's heavily, along with normal customer usage.

Using Auth0 to Authorize API requests from both our SPA and our other back-end services

We have a Single Page App which calls our back-end services (C# and Python), authorizing these requests using the Auth0 SPA flow.
Our back end services only make requests to each other as part of processing a request from an SPA user, so currently we just forward the Authorization header from the SPA request, using it to authorize the operation on each called service.
I now want to add back-end processing jobs that will make requests between our services, making calls to the existing endpoints. These requests will will not have any existing auth header to forward, so will need to construct their own.
Based on the Auth0 docs, here and here, I believe I ought to authorize these requests using a Client Credentials Grant, and I infer that our existing endpoints will therefore need to accept requests authorized in two different ways: from the SPA or from other services.
The problem is that JWTs from the SPA are signed using one secret key, while those from services are signed using their respective secret keys. Am I right that I need to configure my endpoints so that they will accept JWTs constructed using any of these secret keys?
So my core question is: Is this understanding correct, or should I be doing it a different way altogether?
Details:
The two types of Authorization JWT tokens that our endpoints will need to handle are:
1 Requests from our SPA, containing:
sub: SPA-USER-ID
aud: SPA-CLIENT-ID
signed using HS256 (for historical reasons) using our SPA's client secret.
2 Service-to-service requests, containing:
sub: SERVICE-ID#clients
aud: API-ID
scope: ""
signed using HS256 (for now to keep things simple) using our calling service's client secret.
If one endpoint is going to decode and verify both requests, firstly it will fail because 'aud' values are different. I think the 'aud' value of our existing SPA calls is an error - it ought to be the ID of the API receiving the request. Then the 'aud' values in both requests will be the same.
The next difference is that they are each signed with a different secret key - either the SPA's or the calling service's (and potentially with a different algorithm too, if I chose to make the new service calls using RS256 as Auth0 recommends.)
I can't spot obvious ways to modify the Python and C# quickstarts to accept tokens encoded with different keys. I'm thinking about coding it myself, to manually try one, and if it fails then try the other. I'm confident I can do it for the Python endpoint authorization, which I wrote myself based on the Auth0 quickstart using PyJWT, but less familiar with our C# stuff, which is also based on an Auth0 quickstart but seem to use some built-in .NET JWT validation middleware, and I'm not at all sure I can get at its innards to add the above functionality.
But if I'm doing this the right way, then surely this is a common requirement?
Apologies if this question is badly-formed, I'm know nothing about auth, and am reading the Auth0/Oath2 docs to figure it out as I go.
(Answering my own question, in the third person)
Is this understanding correct, or should I be doing it a different way altogether?
The overall flow outlined in the question is correct. However there is one pervasive misunderstanding:
When services (or the SPA) request new access tokens from Auth0 (or any issuer), the secret key they provide is not usually the one that Auth0 uses to sign the returned token. Instead, the issuer uses the secret key of the audience (the API that will be called using this access token.)
The reason the OP got confused about this is because the code he inherited, as noted in the question, incorrectly passes an 'audience' value of the SPA itself when requesting tokens. Hence the resulting tokens are signed using the SPA's secret. Once this is fixed, to use the API ID as the 'audience', then the tokens generated for the SPA and those generated for service-to-service calls will all:
contain audience=API-ID, and hence will contain equivalent payloads in all regards except for 'sub' (user id) and 'scope' (currently unused.)
be signed with HS256 using the API-SECRET of the audience.
Hence, an endpoint doesn't have to check two different types of tokens encoded using two different secret keys. It can just check incoming requests using it's own 'audience' identifier, and its own secret key, and this will successfully decode and validate requests from both the SPA and from other services.

How to get started with OAuth to secure a Web API application?

I have a Web API application and I've understood OAuth would be the standard security model for APIs where an Authentication Server would become responsible to generate Authorization Tokens so that the user can send to our server and consume the services.
I'm very new to this but I understand the roles involved:
Resource Owner
Client
Resource Server
Authorization Server
But what is OAuth exactly in practice, not in theory? Is it a .NET library? Is it a service provided by a separate Company? Is it something I can configure on my local development machine and see how it works?
How to get started with OAuth to secure a Web API application?
OAuth is a protocol; the current version is OAuth 2.0. More to your question, that link lists several implementations of the protocol in various technologies. For use with the .NET Web API you're probably interested in DotNetOpenAuth which provides implementations of both OAuth 1 and OAuth 2.
I'm using DotNetOpenAuth in an app I'm working on now to secure a .NET Web API. I've got an OAuth2Handler which extends DelegatingHandler which is inserted into the Web API pipeline before incoming requests reach any controllers. OAuth2Handler does the following:
Instantiates a DotNetOpenAuth ResourceServer
Calls ResourceServer.GetPrincipal() which reads and decrypts an access
token (issued elsewhere by the AuthorizationServer and returns an
OAuthPrincipal (In my case I'm reading additional data that the DotNetOpenAuth implementation allows you to pass and creating a ClaimsPrincipal.)
Assigning the IPrincipal containing the user information read from the access token to the User property of the thread and current HTTP context so it is available from the ApiController.User property in the service controllers: httpContext.User = Thread.CurrentPrincipal = principal;
Honestly, getting this all working (e.g. setting up the authorization server, resource server, certificates, etc.) isn't trivial. Unfortunately there didn't seem to be a good guide on the DotNetOpenAuth site. Here's a few other tasks you'll have ahead of you if you go this route:
Implement IAuthorizationServer - This is the interface provided by
DotNetOpenAuth that allows you to plug in to the library and use
their implementation to issue OAuth2 access tokens. You'll also need to implement INonceStore and ICryptoKeyStore which I did using an EntityFramework context for storage.
Configure Certificates - The AuthorizationServer and ResourceServer each use certificates to encrypt/decrypt the access token ensuring they are only accessible to each other. I built some custom configuration so I could manage this configuration in the web.config files of my authorization server app and my Web API services (resource server).
Manage Refresh Token - When first requesting an access token from the authorization server you'll get back (depending on your configuration) both an OAuth2 refresh token and an access token. The services use the access token which should be short-lived. The refresh token is used to get more access tokens. The refresh token should be kept secret (whatever that means in your scenario). For me it means the refresh token is never exposed to client-side javascript in my web app.
I hope that helps give you a high level idea of how to get started with OAuth and .NET Web API. Here's a blog post demonstrating some of these steps. This SO answer gives a few more high level details of the client side of the picture.
(The DotNetOpenAuth online docs appear to be down right now... sorry for no links to them; Apparently it has happened before).

Categories