Orchard Core, Open ID and GraphQL

A first look at how to invoke Orchard Core’s GraphQL API endpoint using Postman

Sipke Schoorstra
Dec 7, 2019 · 8 min read
Photo by Caspar Camille Rubin on Unsplash

As I’m easing back into Orchard Core development, I’m running into little learning curves here and there. It’s been a while since I’ve been actively involved with the Orchard Core project, so it’s natural to be a little bit out of touch with how things work. It’s also natural for me to just dig in and figure it out and share my learnings.

So here’s a little learning about Orchard Core and GraphQL.

Enabling the GraphQL feature was easy. But then I had to figure out what URL to send my queries to. When I figured that out, I was getting a HTTP 401 Unauthorized response.

As it turns out, there are essentially two ways about this:

  1. Grant the Anonymous user role the Execute GraphQL permission, or;
  2. Enable the Open ID Server feature and create an Open ID Application representing your client application. This application stores a Client ID and Client Secret that are used to request a Json Web Token, JWT for short. This JWT is then used as a bearer token when sending GraphQL queries to the GraphQL endpoint.

Let’s see how all of this works in more detail.

Objective

Here’s what we’ll achieve:

  1. Expose a GraphQL endpoint from Orchard to allow content querying.
  2. Invoke the GraphQL endpoint from a client application. This could be plain vanilla JS, Angular, React, Blazor, and so on. I’m just gonna use Postman to try out the GraphQL endpoint. Once that works, we can do it from any other client application.

Orchard Setup

I’m assuming you understand how to setup an Orchard Core CMS website. If not, I recommend you go through the Getting started tutorial first.

When you’re on the Setup screen, make sure to select the Blog recipe, as it will create the BlogPost content type and a sample blog post content item that we’ll use in the GraphQL query.

Enabling the GraphQL Feature

The first order of business is to enable the GraphQL feature. Go to the admin dashboard and look at the left menu. Select Configuration -> Features and search for GraphQL and select the Enable button.

Select “Enable” to enable the GraphQL feature.

The Configuration menu will now have an additional menu item called GraphiQL. GraphiQL is an in-browser IDE for exploring GraphQL and enables you to try out queries. One of the most powerful features of GraphQL is its strongly-typed schemas, which enables GraphiQL to provide autocomplete functionality as we explore the available types.

For example, if you wanted to query all blog posts, you could write the following query:

query BlogPosts {
blogPost {
markdownBody {
html
}
}
}

Thanks to the schema and the GraphiQL UI, we don’t have to go through the source code to figure out all of the available types. Instead, we can simply select the available types and fields to build up our query:

Use the Explorer to select fields to include in the query.

In addition to selecting fields to query, you can also leverage the alt+enter key combination in the query editor to invoke autocomplete:

Press ALT+ENTER to invoke autocomplete.

When you hit the Play button. te query will be executed:

Select “Play” to execute the query.

When I first saw this, it blew my mind. Being able to specify queries that return the exact amount of information I need for my SPA application is an exciting feat indeed! Compare this with having to maintain RESTful APIs that return DTOs tailored to clients. If you have one client, it’s OK. But once you start having both an Admin client and a front-end client for example, already things tend to become somewhat in-elegant. With GraphQL, I can simply expose a single API endpoint and allow clients to query what they need.

Now let’s see how we can invoke this endpoint using Postman.

Invoking the GraphQL Endpoint using Postman

Invoking the GraphQL endpoint can be done in a variety of ways, but first one must know its endpoint URL. By default, its the following path:

/api/graphql

The GraphQL endpoint can be invoked in the following ways:

  1. Using HTTP GET and specifying the query as a querystring value.
  2. Using HTTP POST with content-type set to application/json.
  3. Using HTTP POST with content-type set to application/graphql.

For more details on these options, make sure to checkout the Orchard Core GraphQL documentation.

We’re going to give the HTTP POST / content-type = application/graphql option a try. Specifically, we will query all BlogPost content types.

The complete HTTP request looks something like this:

POST /api/graphql HTTP/1.1
Host: localhost:8396
Content-Type: application/graphql
query {
blogPost {
markdownBody {
html
}
}
}

Here’s what it looks like in Postman:

Postman

Make sure to set the content-type to application/graphql, like so:

Content-Type is set to application/graphql

This looks good. However, when selecting the Send button, the response may not be what you might have expected. At least, I didn’t:

HTTP 400 Bad Request

While debugging to understand what the reason might be for the Bad Request, I noticed that in fact, the GraphQL Middleware component responded with a HTTP 401 Unauthorized status code. I’m not sure how that resulted in a HTTP 400 Bad Request status in Postman, but I figured that I should at least figure out how to deal with the Unauthorized response first.

There are two ways to deal with this, and the best way depends on your use case:

  1. Grant the Execute GraphQL permission to the Anonymous user role.
  2. Create an Open ID Connect Application and use its Client ID and Client Secret to request an access token (a JWT). Use this access token when making GraphQL requests.

We’ll take a look at both options. First, we’ll try option 1:

Granting the Execute GraphQL permission to the Anonymous user role

If your site content is allowed to be publicly available and you have for example a static a front-end application built with Angular, then the best option might be to just allow anyone to make GraphQL requests. This allows your SPA application to invoke the GraphQL endpoint directly, without having the request to be proxied through a back-end controller or middleware.

To allow for this, follow these steps:

  1. Select the Security -> Roles menu item from the admin menu.
  2. Select the Edit button for the Anonymous role.
  3. Search for the “Execute GraphQL” permission and check its “Allow” checkbox.
  4. Select the Save button at the very bottom of the screen.

Now try to execute the HTTP request from Postman again. This time, we see success:

A successful GraphQL response.

Making Authenticated GraphQL Calls

In order to make authenticated calls, the caller needs to have the ExecuteGraphQL permission. In the previous example, we assigned this permission to the Anonymous role, effectively granting this permission to anonymous users.

But this might not always be desirable. For example, you may want to control what applications are allowed to execute GraphQL queries.

Fortunately, Orchard makes this again very easy for us. As it turns out, the Open ID module provides a feature that allows us to create an OAuth2 application, which enables all of the OAuth2 grant types we want to support.

A Grant Type is also known as a Flow.

In this example, we’ll use the OAuth 2.0 Client Credentials Grant type.

First, make sure to remove the Execute GraphQL permission from the Anonymous role.

Then enable the following two features:

  • OpenID Authorization Server
  • OpenID Token Validation

The OpenID token Validation feature enables Bearer token validation.

With these features enabled, select Security → OpenID Connect → Settings → Authorization Server from the admin menu and check the Allow Client Credentials Flow. Make sure to select the Update the server settings and reload the tenant button at the very bottom of the screen.

OpenID Connect Authorization Server settings.

Next, select the OpenID Connect → Management → Applications menu item from the admin menu and select the Add an application button.

You can provide any value you like in the Client id, Display Name and Client Secret fields. Just make sure to also check the Allow Client Credentials Flow checkbox. I entered the following values:

  • Client id: e0f660a2cf2a47babac40a4a8c24e7e0
  • Display Name: Postman
  • Type: Confidential client
  • Client Secret: 76945d3917a4456db5a41fc2949d6439
  • Client Credentials Roles: Administrator

Make sure to take a note of the Client Secret, because it will not be displayed again.

Select the Save button to create the application.

Notice that I selected the Administrator role for the application. Be aware that this grants your application administrative access to the Orchard Core tenant (which includes the Execute GraphQL permission, which is why I chose this role). A safer option would be to create a separate role that has only the Execute GraphQL permission applied.

Requesting Access Tokens

Now that we have an application representing our Postman client, we can use the client credentials to request an access token. The HTTP request looks like this:

POST /connect/token HTTP/1.1
Host: localhost:8396
Content-Type: application/x-www-form-urlencoded
client_id=e0f660a2cf2a47babac40a4a8c24e7e0&client_secret=76945d3917a4456db5a41fc2949d6439&grant_type=client_credentials

Invoking that request yields the following JSON response:

{"token_type":"Bearer","access_token":"CfDJ8GB7ya...trimmed...","expires_in":3600}

Our access token is provided via the access_token field, which we use when creating GraphQL requests, such as the following:

POST /api/graphql HTTP/1.1
Host: localhost:8396
Content-Type: application/graphql
Authorization: Bearer CfDJ8GB7ya...trimmed...
query {
blogPost {
markdownBody {
html
}
}
}

Now we get back a valid HTTP 200 response again.

Summary

In this article, we’ve seen how to enable & invoke the Orchard Core GraphQL endpoint. In order to be able to invoke this endpoint the caller must have the Execute GraphQL permission assigned. We’ve seen how to assign this permission to a user role and how to create an OAuth2 Application and assign a role to it. We then used the application’s credentials to request an access token, which is sent as a bearer token alongside GraphQL requests.

Being able to query Orchards GraphQL endpoint is a powerful feature and makes it easy to use Orchard Core as a headless CMS. Clients can simply request content that they need, and thanks to GraphQL’s flexibility, even shape the returned response.

The Startup

Medium's largest active publication, followed by +568K people. Follow to join our community.

Sipke Schoorstra

Written by

Software Developer

The Startup

Medium's largest active publication, followed by +568K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade