Chapter 2 - jayharris/workshop-oidc GitHub Wiki
# From ./
dotnet new console --name ConsoleClient --output ./src/ConsoleClient/
dotnet sln add ./src/ConsoleClient/ConsoleClient.csproj
# From ./src/ConsoleClient
dotnet add package IdentityModel
Add the necessary Using statements.
ConsoleClient\Program.cs
using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
Add an async Main method
ConsoleClient\Program.cs
replace contents of Program
class with:
public static void Main(string[] args)
{
Console.Title = "Identity Server Console Client";
MainAsync().GetAwaiter().GetResult();
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
private static async Task MainAsync()
{
}
ConsoleClient\Program.cs
within the Program
class:
private const string Authority = "http://localhost:5000";
ConsoleClient\Program.cs
within the MainAsync
method of the Program
class:
var client = new HttpClient();
var discoveryResponse = await client.GetDiscoveryDocumentAsync(Authority);
if (discoveryResponse.IsError) throw new ApplicationException(discoveryResponse.Error);
Console.WriteLine("Successful endpoint discovery");
# From ./src/IdentityProvider/
dotnet run
# From ./src/ConsoleClient
dotnet run
# Expected result: Exception: "Keyset is missing"
In IdentityProvider\Startup.cs
, modify the method signature of the constructor to add an IHostingEnvironment
variable and use that to initialize a class property.
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IHostingEnvironment Environment { get; }
In IdentityProvider\Startup.cs
, append to ConfigureServices
:
if (Environment.IsDevelopment())
{
identityServerBuilder
.AddDeveloperSigningCredential();
}
else
{
throw new Exception("Add Production signing credentials");
}
# From ./src/IdentityProvider/
dotnet run
# From ./src/ConsoleClient
dotnet run
# Expected result: "Successful endpoint discovery"
IdentityProvider
add IdentityConfiguration.cs
using System.Collections.Generic;
using System.Linq;
using IdentityServer4.Models;
namespace IdentityProvider
{
public static class IdentityConfiguration
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return Enumerable.Empty<IdentityResource>();
}
public static IEnumerable<ApiResource> GetApis()
{
return Enumerable.Empty<ApiResource>();
}
public static IEnumerable<Client> GetClients()
{
return Enumerable.Empty<Client>();
}
}
}
Update IdentityProvider\Startup.cs
within the ConfigureServices
method:
// .AddInMemoryIdentityResources(Enumerable.Empty<IdentityResource>())
.AddInMemoryIdentityResources(IdentityConfiguration.GetIdentityResources())
//.AddInMemoryApiResources(Enumerable.Empty<ApiResource>())
.AddInMemoryApiResources(IdentityConfiguration.GetApis())
//.AddInMemoryClients(Enumerable.Empty<Client>())
.AddInMemoryClients(IdentityConfiguration.GetClients())
Add a client to IdentityProfier\IdentityConfiguration.cs
within the GetClients
method:
return new List<Client>
{
new Client
{
ClientId = "ConsoleClient",
ClientName = "Identity Server Console Client",
ClientSecrets =
{
new Secret("secretKey".Sha256())
},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { "protectedApi" }
}
};
Add an API resource to IdentityProfier\IdentityConfiguration.cs
within the GetApis
method:
return new List<ApiResource>
{
new ApiResource("protectedApi", "Sample API")
};
ConsoleClient\Program.cs
within the Program
class:
private const string ClientId = "ConsoleClient";
private const string ClientSecret = "secretKey";
private const string ClientScope = "protectedApi";
ConsoleClient\Program.cs
append to the MainAsync
method of the Program
class:
// request token
var tokenRequest = new ClientCredentialsTokenRequest {
Address = discoveryResponse.TokenEndpoint,
ClientId = ClientId,
ClientSecret = ClientSecret,
Scope = ClientScope
};
var tokenResponse = await client.RequestClientCredentialsTokenAsync(tokenRequest);
if (tokenResponse.IsError) throw new ApplicationException(tokenResponse.Error);
Console.WriteLine($"Identity Response Code: {(int) tokenResponse.HttpStatusCode} {tokenResponse.HttpStatusCode}");
Console.WriteLine($"Token Response:\n{tokenResponse.Json}\n\n");
# From ./src/IdentityProvider/
dotnet run
# From ./src/ConsoleClient
dotnet run
# Expected result: A returned Token Response, a JSON object with an `access_token`