Chapter 5 - jayharris/workshop-oidc GitHub Wiki
Chapter 5: Identity Resources and Scope
5.1: Create another Console Client, repeating 2.1-2.5 for the new client
# From ./
dotnet new console --name IdentityResourceClient --output ./src/IdentityResourceClient/
dotnet sln add ./src/IdentityResourceClient/IdentityResourceClient.csproj
Install IdentityModel NuGet Packages
# From ./src/IdentityResourceClient
dotnet add package IdentityModel
Make Main Method Asynchronous.
Add the necessary Using statements.
IdentityResourceClient\Program.cs
using System.Net.Http;
using System.Threading.Tasks;
using IdentityModel.Client;
Add an async Main method
IdentityResourceClient\Program.cs
replace contents of Program
class with:
public static void Main(string[] args)
{
Console.Title = "Identity Resource Console Client";
MainAsync().GetAwaiter().GetResult();
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}
private static async Task MainAsync()
{
}
Add a constant for the Provider URL
IdentityResourceClient\Program.cs
within the Program
class:
private const string Authority = "http://localhost:5000";
Send a discovery request to the provider
IdentityResourceClient\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");
Run the Provider and test the Console
# From ./src/IdentityProvider/
dotnet run
# From ./src/IdentityResourceClient
dotnet run
# Expected result: "Successful endpoint discovery"
5.2: Add a new Identity Resource and Client configuration to the Identity Provider
Add Identity Resources to IdentityProfier\IdentityConfiguration.cs
within the GetIdentityResources
method:
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
Add a client to IdentityProfier\IdentityConfiguration.cs
within the GetClients
method:
new Client
{
ClientId = "IdentityResourceClient",
ClientName = "Identity Resource Console Client",
ClientSecrets =
{
new Secret("secretKey".Sha256())
},
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowedScopes = { "openid","profile" }
}
5.3: Add constants for the Client configuration
ConsoleClient\Program.cs
within the Program
class:
private const string ClientId = "IdentityResourceClient";
private const string ClientSecret = "secretKey";
private const string ClientScope = "openid profile";
private const string UserName = "[email protected]";
private const string UserPassword = "AwesomePassword4U!";
5.4: Send a Token request to the provider
ConsoleClient\Program.cs
append to the MainAsync
method of the Program
class:
// request token
var tokenRequest = new PasswordTokenRequest {
Address = discoveryResponse.TokenEndpoint,
ClientId = ClientId,
ClientSecret = ClientSecret,
Scope = ClientScope,
UserName = UserName,
Password = UserPassword
};
var tokenResponse = await client.RequestPasswordTokenAsync(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");
5.5: Run the Provider and test the Console
# From ./src/IdentityProvider/
dotnet run
# From ./src/ConsoleClient
dotnet run
# Expected result: A returned Token Response, a JSON object with an `access_token`
5.6: Request User Claims
ConsoleClient\Program.cs
append to the MainAsync
method of the Program
class:
// request userInfo
var userInfoRequest = new UserInfoRequest {
Address = discoveryResponse.UserInfoEndpoint,
Token = tokenResponse.AccessToken
};
var userInfoResponse = await client.GetUserInfoAsync(userInfoRequest);
Console.WriteLine($"UserInfo Response Code: {(int) userInfoResponse.HttpStatusCode} {userInfoResponse.HttpStatusCode}");
if (userInfoResponse.IsError)
{
Console.WriteLine($"UserInfo Error Response: {userInfoResponse.Error}");
throw new Exception(userInfoResponse.Error);
}
Console.WriteLine("User Claims:");
foreach (var claim in userInfoResponse.Claims)
{
Console.WriteLine($"{claim.Type}: {claim.Value}");
}
5.7: Run the Provider and test the Console
# From ./src/IdentityProvider/
dotnet run
# From ./src/ConsoleClient
dotnet run
# Expected result: A returned User Info Response, 200 OK with a JSON object showing the user's identifying information.