Skip to content
Herb Stahl edited this page May 29, 2019 · 18 revisions

What does this app do and why do I want it?

This project is a GraphQL.NET based starter kit that uses a plugin model when bringing in new APIs. The goal was to make it as simple as possible when adding APIs by fully adopting how APIs are writing with the GraphQL.Net Project.

alt text

APIS

GraphQL.Play uses the GraphQL.Net Project and there is an example of converting an graphql-dotnet/example-orders into a plugin.

If you want to learn how to write GraphQL APIs, then go to GraphQL.Net Project.

The kit includes a stock Token Exchange API, which follows the same plugin model that all subsequent APIs will follow. The Token Exchange is a must-have API if any serious thought is given to securing your services.

OAuth2

IdentityServer4 is used as the OAuth2 engine. So out of the box, you get stuff like client_credentials flows. I use the client_credentials flow when I want to allow B2B access to APIs. Being also a compliant OAuth2 service, thanks to IdentityServer4, you get all the discovery and token endpoints you would expect.

There are also extension grants available that are basically a la carte apis to the OAuth2 token endpoint to mint arbitrary tokens.

Extension Grants

arbitrary_no_subject
arbitrary_identity
arbitrary_resource_owner

Authorization

The project adopts OAuth2 bearer token authorization. The access_tokens that are needed are minted by the application using IdentityServer4 as the minter. For our purposes IdentityServer4 is a way better JWT library than the one that Microsoft supplies. The IdentityServer4 one accounts for an operational store that you need if you want to mint refresh_tokens and reference access_tokens, and stores that house your clients configurations. Redis and CosmosDB are options, as is using KeyVault to manage certificates.

Once you author an API, you configure in the security that is required to access it. Typically this is stating that your graph queries require auth and must have the following claims. The kit will honor that before you are ever called. An appsettings example can be seen here.

token exchange

OAuth 2.0 Token Exchange
I don't fully buy into what is going on with the draft spec, simply because exchanging something for something else is a private matter. So I would find it interesting if anyone could build a reference implementation to the spec. I put it here to point out that folks are giving a lot of thought to it.

Other examples of exchanges.
AWS Security Token Service

Token Exchanges are the cool part of the kit. In real life, you exchange your id_token (drivers license) for an access_token(a Tyvek wristband) when you want to gain access to some club. The enforcer of the rules set forth by the club owner is typically a bouncer. Those rules are private to the club and can change anytime. In short, the resulting access_token( a Tyvek wristband) is private to the club and no reasonable person would think that it will be accepted down the street at another club.

NOTE: your id_token doesn't give you access to anything. It is nothing more than proof of identity that is being vouched for by a third party that is acceptable to an enforcer.

The kit comes with a pipeline exchange where an external POST handler is all that is needed to be part of the pipeline as the final exchange External-Token-Exchange. The pipeline exchange allows for in-proc plugins to be registered as well-known pre-processors but for most things you may not need to extend the core app.

You can use the TokenExchange concept to build out an Authorization Service.

2 Kits in One

For those that really love microservice you could spin up 2 versions of this where your OAuth2 and TokenExchange are in one service and your API ONLY WebApp are in another. Your APIs micro service would simply refer to the first one as its authorization authority.

I personally like monoliths but in a pinch can spawn off a microservice. In the end, you are trading one problem for another.
For the monolith approach, start with the TokenExchange app and keep adding APIs to it.