This series simulates a native application accessing a protected Web API resource, using OAuth2 via IdentityServer3. It demonstrates using Proof Key for Code Exchange (PKCE), and is in four parts:

  1. Build a simple authorization server, consumed by native application.
  2. Build a protected resource.
  3. Persist server configuration to database.
  4. Persist user data to database using Microsoft.Identity and SQL Server.

This series does not create an OpenID Connect (OIDC) server. It is OAuth-only, since the PKCE specification doesn't require OIDC.

Where We're At

We can get a token, but there's nothing to use it on. We've configured IdentityServer with information about our client application (PretendMobile), and we used that information (Client ID, etc) to get a token.

Now we'll add a Web API with a protected method that just returns some claim data. It will be configured to:

  1. Accept the access token our pretend mobile app gets from the authorization server.
  2. Validate that token against the authorization server.

We'll use the same project as the authorization server, but it's important to know that the Web API could be in a completely separate project.


Simplest OAuth Server
Simplest OAuth2 Walkthrough Code

Install the packages for Web API, and being able to accept the IdentityServer tokens. Note IdentityModel version, which is latest for .Net 4.6 (2.x is for .Net Core).

Install-Package Microsoft.AspNet.WebApi.Client -Version 5.2.3 -Project AuthAndApi
Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.2.3 -Project AuthAndApi
Install-Package IdentityModel -Version 1.9.2 -Project AuthAndApi
Install-Package IdentityServer3.AccessTokenValidation -Version 2.15.0 -Project AuthAndApi

Add two things to the OWIN pipeline: accepting access tokens, and using WebApi.

Updated Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IdentityServer3.Core.Configuration;
using Owin;
using AuthAndApi.IdOptions;
using AuthAndApi.IdUsers;
using System.Web.Http;
using IdentityServer3.AccessTokenValidation;

namespace AuthAndApi
    public class Startup
        public void Configuration(IAppBuilder app)
            //Configure IdentityServer for issuing authentication tokens
            var options = new IdentityServerOptions
                Factory = new IdentityServerServiceFactory()
                //SSL MUST be used in production
                RequireSsl = false

            // Configure Web API to accept access tokens from IdentityServer, and require a scope of 'email'
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                //In this case, the authorization server is also the Web API server
                Authority = "http://localhost:27230",
                ValidationMode = ValidationMode.ValidationEndpoint,
                RequiredScopes = new[] { "email" }

            //Configure Web API
            var config = new HttpConfiguration();

Add a Controllers folder, and a controller named Test.


Create an API method that requires authorization. The method checks for evidence a user authorized (and not just the application).

Code shamelessly stolen from the IdentityServer samples


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Security.Claims;

namespace AuthAndApi.Controllers
    public class TestController : ApiController
        public IHttpActionResult Get()
            var user = User as ClaimsPrincipal;

            var subjectClaim = user.FindFirst("sub");
            if (subjectClaim != null)
                return Json(new
                    message = "OK user",
                    client = user.FindFirst("client_id").Value,
                    subject = subjectClaim.Value,
                    email = user.FindFirst("email").Value
                return Json(new
                    message = "User claim not found for this client_id",
                    client = user.FindFirst("client_id").Value

The API server now has a protected resource. Let's prove it requires authorization. Run the application. The console will still get an access token, but we're not doing anything with it, yet. Leave the project running and manually enter this URL into a browser to try to access the protected resource.


The server will return something like this:

  <Message>Authorization has been denied for this request.</Message>

Pretend Mobile App - Access Protected Resource

In the PretendMobile project, add and call a method that access the protected Web API resource. The token is added to the request in the Authorization header.

        static void Main(string[] args)
            //get token
            var response = GetAccessToken();
            Console.WriteLine("Access Token: " + response.AccessToken);
            //use token

        static void CallProtectedApiResource(string access_token)
            var client = new HttpClient();

Run the solution. After authorizing, the application successfully gets the protected resource's data.


Wrap Up

We now have a fully functioning mobile application! Next up, persisting the IdentityServer configuration.