Boilerplate for: Asp.NET 5 IdentityServer4, Angular CLI, and Asp.NET 5 WebAPI
This project is a boilerplate for Asp.NET 5 IdentityServer4, Angular CLI, and Asp.NET 5 WebAPI. The included IdentityServer4 server is dependent on Entity Framework, SQL Server, and the Asp.NET Identity System, although these dependencies can be swapped for custom services / alternative database services if desired. The project comes pre-configured with an implicit flow client that is configured to the provided Angular CLI webapp via Open ID Connect (OIDC) using the npm packages angular-oauth2-oidc and angular-oauth2-oidc-jwks. The Angular CLI project is empty aside from these dependencies, the example login logic, and 1 example call to the protected Resource WebAPI server.
- The IdentityServer4 server (
IdentityServer.csproj) is configured to run in development at the following 2 URIs: - The Angular CLI project (
/Angular-WebApp) can be started in development by runningng servefrom the command line in the root of the Angular-WebApp folder and visiting http://localhost:4200. To get started with Angular CLI, check out the Angular provided Tour of Heroes app and Tutorial. - The Asp.NET 5 WebAPI project (
ResourceServer.csproj) is configured to run in development at the following 2 URIs: - SQL Server can be easily setup using DockerHub for SQL Server for either Linux or Window machines.
- First, set the Globals.cs variables.
- Next, set the Angular CLI webapp variables.
- Configure desired 3rd Party Authentication.
- Configure for either Https (recommended) or Http.
- Set any additional variables.
- Start the IdentityServer4 server to auto-create / migrate your database specified in the
Connection_Stringvalue in Globals.cs. Next start the Asp.NET 5 WebAPI. Runng servefrom the command line in the Angular-WebApp folder to start the development Angular CLI webapp. Your boilerplate is now complete!
- Set Globals.cs Variables
- Set the Angular CLI Webapp Variables
- Configure for 3rd Party Auth
- Configure for Https
- Configure for Http
- Additional Settings
- Additional Info
Open the Visual Studio solution, find the Variables project, and set the required Globals.cs variables for your environment. These variables include:
- Required variables
Client_Id- A unique identifier for your implicit client. More information regardingClient_idselection is available in Section 2.2 of the RFC.Api_Resource_Name- The name of the Resource Server which will be validated as the Issuer in theUseJWTBearer()call in Startup.csConfigureServices()of the Resource Server WebAPI project.// This is for access tokens services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = globals.IDENTITYSERVER_HTTPS_URI; options.RequireHttpsMetadata = false; options.Audience = globals.API_RESOURCE_NAME; });
Api_Resource_Scope- A scope registered to the implicit client in the IdentityServer4 server database that a Resource Server can request.Connection_String- A SQL server connection string to your SQL Server instance to store the database. An example template connection string is below:Server=;Database=;Trusted_Connection=false;User Id=;Password=;MultipleActiveResultSets=true
Admin_Password- The password of the Admin user. Requires at least 8 characters with 1 lowercase, 1 uppercase, 1 number, and 1 special character (!, %, &, etc.).Admin_User_Email- The email registered as a claim for the Admin user.
- Variables to change when pushing to production
Certificate_Password- The private key you specified when creating your .pfx ssl certificate.Client_Uri- The Uri for the implicit client (the Angular CLI webapp). Defaults to localhost:4200.Client_Redirect_Uri- The Uri the browser will be redirected to after a successful login. Defaults to http://localhost:4200.Client_Post_Logout_Redirect_Uri- The Uri the browser will be redirected to after a successful logout. Defaults to http://localhost:4200.Client_Allowed_Cors_Origins- An array of strings containing valid origin Uris from which to request authorization from the IdentityServer4 server. Defaults to string[] { http://localhost:4200 }.
- Optional admin user / claims variables that can be specified
Admin_Username- The username of the Admin user. Defaults toadmin.Admin_User_Full_Name- The full name of the Admin User.Admin_User_Given_Name- The given (first) name of the Admin user.Admin_User_Family_Name- The family (last) name of the Admin user.Admin_User_Website- The website of the Admin user registered as a claim.Admin_Role- The default role for the Admin user. Defaults toadmin.
- Other variables that can be changed if the hosting Uris are modified
IdentityServer_Http_Uri- The Uri where the development IdentityServer4 server is hosted over Http. Defaults to http://localhost:5000.IdentityServer_Https_Uri- The Uri where the development IdentityServer4 server is hosted over Https. Defaults to https://localhost:5001.WebApp_Uri- The Uri where the development Angular CLI webapp is hosted. Defaults to http://localhost:4200.WebAPI_Http_Uri- The Uri where the development Asp.NET 5 WebAPI is hosted over Http. Defaults to http://localhost:5002.WebAPI_Https_Uri- The Uri where the development Asp.NET 5 WebAPI is hosted over Https. Defaults to https://localhost:5003.
Set the Angular CLI Webapp Variables
Open the Angular CLI webapp project and navigate to src -> app -> services -> globals.service.ts. Set the required variables for your environment which include:
- Required variables
Client_Id- The unique identifier for your implicit client. This should match the value specified in Globals.cs above.Client_Scopes- Space-deliminated list of scopes requested by the Angular CLI webapp. Be sure to includeopenid(required as this boilerplate uses OIDC to connect to the IdentityServer4 server) and theApi_Resource_Scopevalue specified in Globals.cs above.Roleshave been included as an additional identity resource, andprofileis a standard claim for retrieving profile information.- e.g.
openid profile roles api.resource.scope
- e.g.
- Other variables that can be changed if the hosting Uris are modified
IdentityServer_Http_Uri- The Uri where the development IdentityServer4 server is hosted over Http. Defaults to http://localhost:5000.IdentityServer_Https_Uri- The Uri where the development IdentityServer4 server is hosted over Https. Defaults to https://localhost:5001.WebAPI_Http_Uri- The Uri where the development Asp.NET 5 WebAPI is hosted over Http. Defaults to http://localhost:5002.WebAPI_Https_Uri- The Uri where the development Asp.NET 5 WebAPI is hosted over Https. Defaults to https://localhost:5003.WebApp_URI- The Uri where the development Angular CLI webapp is hosted. Defaults to http://localhost:4200.WebApp_Redirect_Uri- The Uri where the development Angular CLI webapp will be redirected to after a successful login. Defaults to http://localhost:4200.WebApp_Post_Logout_Redirect_Uri- The Uri where the development Angular CLI webapp will be redirected to after a successful logout. Defaults to http://localhost:4200.
If you are using multiple 3rd party providers, make sure to call services.AddAuthentication() once and chain your provider calls together like below:
services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "";
options.ClientSecret = "";
})
.AddTwitch(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "";
options.ClientSecret = "";
});- Google
-
Login to the Google Developer Portal and create a new project. Register an OAuth 2.0 client. You will need to specify an
authorized redirect uri(e.g. for development, http://localhost:5000/signin-google or https://localhost:5001/signin-google) and if you like, anauthorized JavaScript origin(e.g. for development, http://localhost:4200). Make note of theClient IdandClient Secretprovides your OAuth 2.0 client - you will need these in the next step. -
In the IdentityServer4 server project Startup.cs
ConfigureServices()method, uncomment the following lines and add in theClient IdandClient Secretyou retrieved in the previous step:services.AddAuthentication() .AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = ""; options.ClientSecret = ""; });
-
In production, you will need to change these Uris to match the domain / Uri where the IdentityServer4 server and Asp.NET 5 WebAPI are hosted.
-
- Facebook
-
Login to the Facebook Developer Portal and create a new app. Add in the specified Uris such as the app domain (
localhostfor development), privacy Uri, and terms of service Uri. On the left under products, click on Facebook Login -> Settings. Make sureClient OAuth LoginandWebOAuth Loginare enabled and optionally enableEnforce Https(if your IdentityServer4 server is being hosted on SSL). Add in theValid OAuth Redirect URIs(e.g. for development, http://localhost:5000/signin-facebook or https://localhost:5001/signin-facebook). Under Settings -> Basic, make note of theapp Idandapp secret- you will need these in the next step. -
In the IdentityServer4 server project Startup.cs
ConfigureServices()method, uncomment the following lines and add in theapp id(as Client Id) andapp secret(as Client Secret) you retrieved in the previous step:services.AddAuthentication() .AddFacebook(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = ""; options.ClientSecret = ""; });
-
In production, you will need to change these Uris to match the domain / Uri where the IdentityServer4 server and Asp.NET 5 WebAPI are hosted.
-
- Twitter
-
Login to the Twitter Developer Portal and create a new project and a new app in the project. Under the details for the app, add in under
callback urlsthe appropriate Uri for your IdentityServer4 server (e.g. for development, http://localhost:5000/signin-twitter or https://localhost:5001/signin-twitter). Click onKeys and Tokenunder the title of the app on the App details page, and underConsumer Keys, create a newAPI Key & Secret. Make note of theapi keyandapp secret- you will need these in the next step. -
In the IdentityServer4 server project Startup.cs
ConfigureServices()method, uncomment the following lines and add in theapi key(as Consumer Key) andapi secret(as Client Secret) you retrieved in the previous step:services.AddAuthentication() .AddTwitter(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ConsumerKey = ""; options.ConsumerSecret = ""; });
- In production, you will need to change these Uris to match the domain / Uri where the IdentityServer4 server and Asp.NET 5 WebAPI are hosted.
-
- Twitch
-
Login to the Twitch Developer Portal and create a new application. Specify the category of the application as
Website integration, and add in the appropriateOAuth Redirect URIs(e.g. for development, http://localhost:5000/signin-twitch or https://localhost:5001/signin-twitch). Make note of theClient IdandClient Secret- you will need these in the next step. -
In the IdentityServer4 server project Startup.cs
ConfigureServices()method, uncomment the following lines and add in theClient IdandClient Secretyou retrieved in the previous step:services.AddAuthentication() .AddTwitch(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = ""; options.ClientSecret = ""; });
-
In production, you will need to change these Uris to match the domain / Uri where the IdentityServer4 server and Asp.NET 5 WebAPI are hosted.
-
- Microsoft
-
Login to Azure portal - App Registrations and create a new app registration. Specify the app registration name and add the appropriate
Redirect Uri(e.g. set it asWeb, and for development, the Uri is either http://localhost:5000/signin-microsoft or https://localhost:5001/signin-microsoft). ClickRegister. Make note of theApplication (client) ID- you will need this in the next step. On the left, click onCertificates & secrets. UnderClient Secrets, add a newClient secretand take note of the value - you will need this in the next step. -
In the IdentityServer4 server project Startup.cs
ConfigureServices()method, uncomment the following lines and add in theClient IdandClient Secretyou retrieved in the previous step:services.AddAuthentication() .AddMicrosoftAccount(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = ""; options.ClientSecret = ""; });
-
In production, you will need to change these Uris to match the domain / Uri where the IdentityServer4 server and Asp.NET 5 WebAPI are hosted.
-
-
Setup Signing Certificate
- Copy a
.pfx certificateinto the wwwroot folder calledcert.pfxfrom a known certified authority (CA) for your desired domain / Uri for the IdentityServer4 server. You will need to export this certificate as a .pfx certificate with a private key that matches the key specified in Globals.cs. If you do not have an SSL certificate for your domain, a free one can be obtained from Let's Encrypt. After obtaining a certificate, you will need to export it with a private key (preferably in the .pfx format).
When the IdentityServer is used in production, the signing SSL certificate will need to be included in the IdentityServer wwwroot called
cert.pfxunless you change the signing certificate logic (below).-
Copy your
cert.pfxinto the IdentityServer4 server wwwroot folder. -
You can modify the certificate logic to fit your needs (i.e. .cer certificate, different name, etc). This logic is located in IdentityServer4 server project Startup.cs
ConfigureServices(approximately lines 90 - 107):if (Environment.IsDevelopment()) { builder.AddDeveloperSigningCredential(); } else { // ** IMPORTANT ** // Required for Production! - Make sure to add cert.pfx into the wwwroot folder // If running in Http (not recommended for production), comment out this entire block! var filename = Path.Combine(Environment.WebRootPath, "cert.pfx"); if (!File.Exists(filename)) { throw new FileNotFoundException("Signing Certificate is missing!"); } var cert = new X509Certificate2(filename, globals.CERTIFICATE_PASSWORD); builder.AddSigningCredential(cert); }
- Copy a
-
Enable HttpsRedirection
-
In the IdentityServer4 server Startup.cs,
Configure(), uncomment (approximately line 170)app.UseHttpRedirection()so Asp.NET 5 WebAPI will automatically redirect all non-secured requested to SSL.app.UseHttpsRedirection();
- In ResourceServer Startup.cs,
Configure(), uncomment (approximately line 91)app.UseHttpRedirection()so Asp.NET 5 WebAPI will automatically redirect all non-secured requested to SSL.
app.UseHttpsRedirection();
- In ResourceServer Startup.cs,
-
-
Verify URIs point to Https
-
By default, all Uris in the solution will point to Https endpoints. If these have changed but you wish to re-enable Https, the following locations should be checked:
-
In the Angular CLI webapp, go to src -> app ->
app.component.ts. At line approximately 21, change theissuerto the Https endpoint:authConfig: AuthConfig = { issuer: this.globalsService.IdentityServer_Https_URI, redirectUri: window.location.origin, clientId: this.globalsService.Client_Id, scope: this.globalsService.Client_Scopes, postLogoutRedirectUri: this.globalsService.WebApp_Post_Logout_Redirect_URI }
-
In the Angular CLI webapp, go to src -> app ->
app.component.ts. At line approximately 18, change the webapi_http endpoint to Https:requestWeatherForecast() { this.httpClient.get<string>(`${this.globalsService.WebAPI_Https_URI}/WeatherForecast`) .subscribe((response: string) => { this.$apiSubject.next(JSON.stringify(response)); }); }
-
In ResourceServer Startup.cs
ConfigureServices(), changeoptions.Authority = globals.IDENTITYSERVER_HTTPS_URI..AddJwtBearer("Bearer", options => { options.Authority = globals.IDENTITYSERVER_HTTPS_URI; options.RequireHttpsMetadata = false; options.Audience = globals.API_RESOURCE_NAME; });
-
-
-
Disable Signing Certificate
- IdentityServer4 requires a TLS / SSL connection - however, you can terminate the SSL connection before the Asp.NET app and pass requests from a reverse proxy to an unsecured port bound to the IdentityServer4 server.
In production, you will still need to include a .pfx SSL certificate with private key called
cert.pfxin the wwwroot folder. You can remove this requirement by commenting / removing the following lines from IdentityServer4 server Startup.cs inConfigureServices()(approximately lines 90 - 107):if (Environment.IsDevelopment()) { builder.AddDeveloperSigningCredential(); } else { // ** IMPORTANT ** // Required for Production! - Make sure to add cert.pfx into the wwwroot folder // If running in Http (not recommended for production), comment out this entire block! // var filename = Path.Combine(Environment.WebRootPath, "cert.pfx"); // if (!File.Exists(filename)) // { // throw new FileNotFoundException("Signing Certificate is missing!"); // } // var cert = new X509Certificate2(filename, globals.CERTIFICATE_PASSWORD); // builder.AddSigningCredential(cert); }
-
Change Uris to Http
-
By default, all Uris in the solution will point to Https endpoints. If you wish to change to Http, the following locations should be checked:
-
In the Angular CLI webapp, go to src -> app ->
app.component.ts. At line approximately 21, change theissuer` to the Http endpoint:authConfig: AuthConfig = { issuer: this.globalsService.IdentityServer_Http_URI, redirectUri: window.location.origin, clientId: this.globalsService.Client_Id, scope: this.globalsService.Client_Scopes, postLogoutRedirectUri: this.globalsService.WebApp_Post_Logout_Redirect_URI }
-
In the Angular CLI webapp, go to src -> app ->
app.component.ts. At line approximately 18, change the webapi_https endpoint to Http:requestWeatherForecast() { this.httpClient.get<string>(`${this.globalsService.WebAPI_Http_URI}/WeatherForecast`) .subscribe((response: string) => { this.$apiSubject.next(JSON.stringify(response)); }); }
-
In ResourceServer Startup.cs
ConfigureServices(), changeoptions.Authority = globals.IDENTITYSERVER_HTTP_URI..AddJwtBearer("Bearer", options => { options.Authority = globals.IDENTITYSERVER_HTTP_URI; options.RequireHttpsMetadata = false; options.Audience = globals.API_RESOURCE_NAME; });
-
-
-
FOR DEVELOPMENT USING HTTP
- In the IdentityServer4 server Startup.cs
Configure(), uncomment (approximately line 167)app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict }). This is required to store unsecured cookies and redirect correctly from the IdentityServer4 server after a successful login on Http.
In production, SSL is required (but can be terminated before the Asp.NET app) and Cookies will always be secured. This line should be commented out / removed for production.
// app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Strict }); - In the IdentityServer4 server Startup.cs
-
If you would like to use
reference tokensinstead ofbearer tokens, you will need to change theclient.AccessTokenTypeand add anApiSecretto theApiResourcein the IdentityServer4 server Config.cs. -
This boilerplate includes commented out code that can be used to change to
reference tokens. The commented code sections are:-
IdentityServer4 server Config.cs
GetClients(),AccessTokenTypeneeds to be changed toAccessTokenType.Reference.return new Client[] { // Angular CLI Client new Client { ClientId = globals.CLIENT_ID, ClientName = "Angular WebApplication", AllowedGrantTypes = GrantTypes.Implicit, RedirectUris = { globals.CLIENT_REDIRECT_URI }, PostLogoutRedirectUris = { globals.CLIENT_POST_LOGOUT_REDIRECT_URI }, // LogoUri = "", AllowedCorsOrigins = globals.CLIENT_ALLOWED_CORS_ORIGINS, RequireConsent = false, AllowAccessTokensViaBrowser = true, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "roles", globals.API_RESOURCE_SCOPE }, EnableLocalLogin = true, ClientUri = globals.CLIENT_URI, AccessTokenType = AccessTokenType.Reference }, };
-
IdentityServer4 server Config.cs
GetApiResources(), the ApiResourceApiSecretsneeds to be un-commented.return new List<ApiResource> { new ApiResource(globals.API_RESOURCE_NAME, "ResourceServer.WebAPI") { // No secrets for Implicit Flow ApiSecrets = { new Secret(globals.API_RESOURCE_SECRET.Sha256()) }, Scopes = globals.WEBAPI_REQUESTED_SCOPES.ToList() } };
-
ResourceServer Startup.cs
ConfigureServers(),AddOauth2Introspection()needs to be un-commented. If the Resource Server is only going to supportreference tokens,AddJwtBearer()can also be be removed.// This is for access tokens services.AddAuthentication("Bearer") //.AddJwtBearer("Bearer", options => //{ // options.Authority = globals.IDENTITYSERVER_HTTPS_URI; // options.RequireHttpsMetadata = false; // options.Audience = globals.API_RESOURCE_NAME; //}); // This is for reference tokens .AddOAuth2Introspection("token", options => { options.Authority = Globals.IDENTITYSERVER_URI; // this maps to the API resource name and secret options.ClientId = Globals.CLIENT_ID; options.ClientSecret = Globals.API_RESOURCE_SECRET; });
-
-
More information regarding
reference tokenscan be found at the IdentityServer4 reference documentation.
If you would like the IdentityServer4 server to automatically redirect the user back to a specified (and authorized) post logout redirect uri after a successful logout, in the IdentityServer4 server Startup.cs ConfigureServices(), uncomment the line specifying AuthRedirectAfterSignOut = true (approximately line 57):
AccountOptions.AutomaticRedirectAfterSignOut = true;For additional information / documentation on how to use the included applications, please see the following links:
- IdentityServer4 Documentation
- AngularCLI Tour of Heroes Example Project
- Asp.NET 5 WebAPI Tutorial
- OAuth 2.0 Protocol
- OIDC Protocol
IdentityServer4-Angular-.NET-5-WebAPI-Boilerplate was created by LiveOrDevTrying and is maintained by Pixel Horror Studios.