User interaction UIs - markglibres/identityserver4-mongodb-redis GitHub Wiki
Auth server with user interaction (OpenId)
Features
- Login / Logout
- Registration with confirmation email
- Forgot password with reset password link
- Customizable email templates using Handlebars.Net
Pre-requisites
- docker (linux)
- docker-compose
- dotnet 3.x (upcoming support for 5.x)
- use https for server and client apps
A. Setup server
-
Create an empty .Net MVC app.
- use the url https://localhost:5001 for this tutorial, otherwise you need to update the config values in next steps
-
Within the root directory of the project, execute this script to download the sample views, templates, sample seed users / clients / api resources, and docker compose file (for mongodb, redis and mailhog)
curl -L https://raw.githubusercontent.com/markglibres/identityserver4-mongodb-redis/master/utils/server_sample.sh | bash
-----skip this step if you don't want to use the sample files
-
Install NuGet package
BizzPo.IdentityServer
dotnet add package BizzPo.IdentityServer
-
Install NuGet package
BizzPo.IdentityServer.Hosts.Server
dotnet add package BizzPo.IdentityServer.Hosts.Server
-
In
Startup.cs -> ConfigureServices
, configure services for Identity User Interactionservices.AddControllersWithViews() .AddIdentityServerUserInteraction();
-
Configure scope to use for user interaction
services.AddControllersWithViews() .AddIdentityServerUserInteraction(config => { config.Scope = "users.management"; });
-
Configure email templates - make sure to set "Content -> Copy always / newer" or "Embedded" for email templates
services.AddControllersWithViews() .AddIdentityServerUserInteraction(config => { //..... config.Emails = new Emails { EmailConfirmation = new EmailConfig { Subject = "Confirm user registration", TemplateOptions = new EmailTemplateOptions { File = "~/Templates/user-email-confirmation.html", FileStorageType = FileStorageTypes.Local } }, ForgotPassword = new EmailConfig { Subject = "Reset password link", TemplateOptions = new EmailTemplateOptions { File = "~/Templates/user-reset-password.html", FileStorageType = FileStorageTypes.Local } } }; });
-
Configure for the built-in user interaction mvc controllers
.AddIdentityServerUserInteractionMvc()
(skip this step if you want to create your own controllers.. TODO: doc on how to send command / query from custom controllers)
services.AddControllersWithViews() .AddIdentityServerUserInteraction(config => { //codes removed for brevity }) .AddIdentityServerUserInteractionMvc();
-
Configure OpenId
services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; });
-
Configure IdentityServer4 with MongoDb and Redis cache
services.AddIdentityServerMongoDb() .AddRedisCache() .AddDeveloperSigningCredential() .AddIdentityServerUserAuthorization<ApplicationUser, ApplicationRole>()
-
Seed clients, scopes and users
services.AddIdentityServerMongoDb() // codes removed for brevity .AddIdentityServerUserAuthorization<ApplicationUser, ApplicationRole>() .SeedUsers<ApplicationUser, SeedUser>() .SeedClients<IdentityServerClients>() .SeedApiResources<UsersApiResource>() .SeedApiScope<UsersApiScopes>() .SeedIdentityResource<SeedIdentityResources>();
-
In
Program.cs -> Main
, initialize the seedspublic static async Task Main(string[] args) { var host = CreateHostBuilder(args).Build(); await host.Services.Initialize(); await host.Services.Initialize<ApplicationUser>(); await host.RunAsync(); }
-
In
Startup.cs -> Configure
, configure request pipeline for IdentityServer.public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //codes removed for brevity app.UseIdentityServer(); app.UseAuthorization(); //codes removed for brevity }
-
In appsettings.json, configure mongodb and redis connection string and smtp options
"Identity": { "Server": { "Authority": "https://localhost:5001", //host url of your identityserver "RequireConfirmedEmail": true, //if user registration requires confirmation of email "Mongo": { //connectionstring for your mongodb "ConnectionString": "mongodb://root:foobar@localhost:27017/?readPreference=primaryPreferred&appname=identityserver", "Database": "Identity" //database name for identityserver }, "Redis": { "ConnectionString": "localhost", // connection string for redis "Db": -1, "Prefix": "test" } } }, "Smtp": { "Host": "localhost", "Port": 1025, "Username": "", "Password": "", "SenderEmail": "[email protected]", "SenderName": "BizzPo IdentityServer", "IsSandBox": false }
-
Run docker-compose file for mongodb, redis and mailhog (smtp server)
docker-compose -f docker-compose-db.yaml up -d
endpoints:
- Auth server: https://localhost:5001/
- Mailhog: http://localhost:8025/
- MongoDb: localhost:27017
- Redis: localhost:6379
NOTE: enable local certificates from Chrome: * chrome://flags/ * enable "Allow invalid certificates for resources loaded from localhost."
-
Run the auth server
dotnet run
. Homepage should show, then browse to the discovery endpoint: https://localhost:5001/.well-known/openid-configuration
Your authorization server is ready, however you need to setup your client app to complete the authorization code flow.
B. Setup client app
-
Create an empty .Net MVC app
- use the url https://localhost:5002 for this tutorial, otherwise you need to update the identity client from previous steps
Within the root directory of the project, execute the script below to download the sample views and controllers
curl -L https://raw.githubusercontent.com/markglibres/identityserver4-mongodb-redis/master/utils/client_sample.sh | bash
-----skip this step if you don't want to use the sample files
-
Install NuGet package
BizzPo.IdentityServer.User.Client
dotnet add package BizzPo.IdentityServer.User.Client
-
In
Startup.cs -> ConfigureService
, configure default authentication schema to OpenIdservices.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; })
-
Configure cookie authentication
services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
-
Configure OpenId connect
services // codes removed for brevity .AddOpenIdConnect("oidc", options => { //the auth server url we configured on previous steps options.Authority = "https://localhost:5001"; // the seeded client from previous steps options.ClientId = "mvc"; options.ClientSecret = "secret"; options.ResponseType = "code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; })
-
Configure to use the user interaction endpoints
services // codes removed for brevity .AddUserManagement(options => { options.AuthenticationScheme = "oidc"; // the user-interaction scope we defined in auth server from previous steps options.Scope = "users.management"; });
-
In
Startup.cs -> Configure
, set to use authenticationapp.UseRouting(); app.UseAuthentication(); app.UseAuthorization();
-
Don't forget to set the CORS policy to allow redirection from your auth server
// Startup.cs -> ConfigureService services.AddCors(options => { options.AddPolicy("All", builder => { builder .WithOrigins("http://localhost:5001") .AllowCredentials() .AllowAnyHeader() .AllowAnyMethod(); }); }); // Startup.cs -> Configure app.UseCors("All");
-
Run the project
dotnet core