Files
Visual-Studio-Templates/WebApplication-Razor/WebApplication-Razor/OpenIDConnect/OpenIDConnectUtils.cs
Karsten Jeppesen e1457a72aa Version 1.0
2025-11-21 08:25:56 +01:00

168 lines
6.3 KiB
C#

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.HttpOverrides;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
// Required NuGet Packages
// Microsoft.AspNetCore.Authentication.JwtBearer
// Microsoft.AspNetCore.Authentication.OpenIdConnect
// Microsoft.IdentityModel.Protocols.OpenIdConnect
// Microsoft.AspNet.WebApi.Core
namespace WebApplication_Razor.OpenIDConnect
{
public class OpenIDConnectUtils
{
// Configuration priority from highest to lowest
// Highest: Command line arguments
// : Non-prefixed environment variables
// : User secrets from the .NET User Secrets Manager
// : Any appsettings.{ ENVIRONMENT_NAME }.json files
// : The appsettings.json file
// Lowest : Fallback to the host configuration
/// <summary>
/// Setting up OpenIDConnect authentication (Program.cs)
/// </summary>
/// <param name="builder">WebApplicationBuilder</param>
public void ConfigureBuild(WebApplicationBuilder builder)
{
// Add services to the container.
builder.Services.AddRazorPages();
MyConfiguration.Set(builder.Configuration);
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = builder.Configuration["OpenIDRealmURI"];
options.ClientId = builder.Configuration["OpenIDClient"];
options.ClientSecret = builder.Configuration["OpenIDSecret"];
options.CallbackPath = "/signin-oidc";
// Authorization Code flow (recommended)
options.ResponseType = "code";
options.SaveTokens = true; // store tokens in auth properties
options.GetClaimsFromUserInfoEndpoint = true;
options.MapInboundClaims = false;
// Scopes - clear then add what's needed
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("ucn");
options.Scope.Add("email");
options.Scope.Add("offline_access"); // to get refresh tokens
// Map claim types if needed
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "roles"
};
// Optional: events for logging / error handling
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = context =>
{
// e.g. add custom claims or logging
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + Uri.EscapeDataString(context.Exception.Message));
return Task.CompletedTask;
}
};
});
// Change here for authorization policies
builder.Services
.AddAuthorizationBuilder()
.AddPolicy("read_access", builder =>
{
// claim, list of acceptable values
builder.RequireClaim("myClaim", "MyClaimValueRO1", "MyClaimValueRO2");
})
.AddPolicy("write_access", builder =>
{
builder.RequireClaim("myClaim", "MyClaimValueRW1", "MyClaimValueRW2");
});
// Require authentication globally (optional)
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/");
});
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
}
/// <summary>
/// Map synthetic endpoints for authentication
/// </summary>
/// <param name="app">WebApplication</param>
public void ConfigureApp(WebApplication app)
{
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages(); // Or app.MapDefaultControllerRoute();
}
public JwtSecurityToken GetJwtPayload(HttpContext myContext)
{
var handler = new JwtSecurityTokenHandler();
return handler.ReadJwtToken(myContext.GetTokenAsync("access_token").Result);
}
public string GetJwtClaim(HttpContext myContext, string theClaim)
{
JwtSecurityToken jwtPayload = GetJwtPayload(myContext);
return jwtPayload.Claims.FirstOrDefault(claim => claim.Type == theClaim).Value;
}
}
static public class MyConfiguration
{
static ConfigurationManager _config;
static public void Set(ConfigurationManager config)
{
_config = config;
}
static public ConfigurationManager Get()
{
return _config;
}
}
}