Setting up an ASP.NET Web Client to use IdentityServer via the OpenID Connect protocol
If you haven’t already, follow the installation steps here first.
Table of Contents
Dependencies
- .Net 7 SDK
- OpenID Connect (support already built into IdentityServer)
Configure the IdentityServer
For this client, we need to configure OIDC in the IdentityServer project.
To enable OIDC in IdentityServer, you need:
- An interactive UI
- Configuration for OIDC scopes
- Configuration for an OIDC client
- Users to log in with
If you already have a UI for the IdentityServer, skip this step. Otherwise, use this quickstart command in the src/IdentityServer directory to add the UI to the project:
dotnet new isuiAdd support for the standard openid and profile scopes by declaring them in src/IdentityServer/Config.cs:
public static IEnumerable<IdentityResource> IdentityResources =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};Then register the identity resources in src/IdentityServer/HostingExtensions.cs:
builder.Services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients);If you need to declare test users, the sample UI comes with an in-memory “user db”, with the users ‘alice’ and ‘bob’, whose passwords and usernames match. Enable this by adding in the Service Collection:
builder.Services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddTestUsers(TestUsers.Users);Lastly, register the ASP.NET Core Web App in the Clients list, found in the src/IdentityServer/Config.cs file:
public static IEnumerable<Client> Clients =>
new List<Client>
{
// interactive ASP.NET Core Web App
new Client
{
ClientId = "web",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
// where to redirect after login
RedirectUris = { "Web App URI/signin-oidc" },
// where to redirect after logout
PostLogoutRedirectUris = {"Web App URI/signout-callback-oidc"},
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
}
}
};Connecting the Client
If you already have a .NET solution and are connecting the client to the IdentityServer, skip this step. Otherwise, if you are starting with a fresh .NET solution, create a new .NET project in the src directory and add it to the solution:
dotnet new webapp -n WebClient
cd ..
dotnet sln add ./src/WebClient/WebClient.csprojFrom the src/WebClient directory, add the OpenID Connect handler pakcage:
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnectConfigure the services in the Program.cs file of the web client:
using System.IdentityModel.Tokens.Jwt;
// ...
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "URI of IdentityServer";
options.ClientId = "web";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
});Then, add the Authentication to the ASP.NET pipeline in Program.cs:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// disable anonymous access for the entire application (if using Razor Pages)
//app.MapRazorPages().RequireAuthorization();Now everything should be in place to log into the Web Client using OIDC. If you run both the IdentityServer and the WebClient project, then navigate to the Web Client home page, you should redirect to the IdentityServer login page. After logging in, you will be redirected back to the home page of the Web Client.
Adding API Access
In order to add API access to the Web Client, we need to modify the Client in the IdentityServer/Config.cs file as so:
// interactive ASP.NET Core Web App
new Client
{
ClientId = "web",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
// where to redirect after login
RedirectUris = { "Web App URI/signin-oidc" },
// where to redirect after logout
PostLogoutRedirectUris = {"Web App URI/signout-callback-oidc"},
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}Then, we need to configure the client to ask for access to the API and for a refresh token. In the Web Client Program.cs file, modify the Authentication Service as so:
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "URI of IdentityServer";
options.ClientId = "web";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("api1");
options.Scope.Add("offline_access");
options.GetClaimsFromUserInfoEndpoint = true;
});Now if you create a page in the Web App, that requests content from the API, it will be authorized using the access token given from the IdentityServer.