OidcStarter.AspNetCore.Bff
1.3.0
dotnet add package OidcStarter.AspNetCore.Bff --version 1.3.0
NuGet\Install-Package OidcStarter.AspNetCore.Bff -Version 1.3.0
<PackageReference Include="OidcStarter.AspNetCore.Bff" Version="1.3.0" />
<PackageVersion Include="OidcStarter.AspNetCore.Bff" Version="1.3.0" />
<PackageReference Include="OidcStarter.AspNetCore.Bff" />
paket add OidcStarter.AspNetCore.Bff --version 1.3.0
#r "nuget: OidcStarter.AspNetCore.Bff, 1.3.0"
#:package OidcStarter.AspNetCore.Bff@1.3.0
#addin nuget:?package=OidcStarter.AspNetCore.Bff&version=1.3.0
#tool nuget:?package=OidcStarter.AspNetCore.Bff&version=1.3.0
OidcStarter.AspNetCore.Bff
BFF-first ASP.NET Core authentication building blocks with secure cookie-backed application sessions.
OidcStarter.AspNetCore.Bff provides built-in OpenID Connect as the default flow, opt-in Google, GitHub, and Facebook providers, and generic custom login-provider registration. Existing consumers can continue using the default single-OIDC login endpoint.
Install
dotnet add package OidcStarter.AspNetCore.Bff
Provider capabilities
| Provider type | Package capability |
|---|---|
| OpenID Connect | Built-in default flow |
| Opt-in registration | |
| GitHub | Opt-in registration |
| Opt-in registration | |
| Custom provider | Generic registration extension point |
Provider availability in a running application or demo depends on its backend configuration; the table describes package capability.
What It Provides
AddOidcStarterBff(configuration)for cookie/OIDC auth, CORS, forwarded headers, authorization, and BFF services.UseOidcStarterBff()for the expected middleware order.- Built-in OpenID Connect login plus opt-in Google, Facebook, GitHub, and generic external login-provider registration.
/api/auth/login,/api/auth/login/{provider},/api/auth/providers,/api/auth/me,/api/auth/csrf, and/api/auth/logoutendpoints.OidcOptionsandOidcStarterBffOptionsconfiguration models.ICurrentUserServiceandCurrentUserResponsefor current-user claim mapping, including additive external identity metadata when available.- A lightweight origin check for logout form posts.
- Antiforgery token groundwork for cookie-authenticated BFF endpoints.
- Authorization policy constants and policy-builder helpers.
- Provider-agnostic role mapping with
IOidcStarterRoleMapper.
Public API Surface
The package keeps its public surface intentionally small:
AddOidcStarterBff(configuration)registers the built-inoidcprovider, BFF services, controllers, authentication, antiforgery, forwarded-header options, CORS, and authorization policies.UseOidcStarterBff()applies the expected middleware order.AddOidcStarterGoogle(...),AddOidcStarterFacebook(...), andAddOidcStarterGitHub(...)add the corresponding opt-in external handlers and provider metadata.AddOidcStarterLoginProvider(...)registers metadata for an authentication scheme that the consuming application has configured separately.AddOidcStarterRoleMapper<TMapper>()registers provider-specific role extraction logic while preserving the default flat-claim mapper.OidcOptions,OidcStarterBffOptions, andRequiredClaimOptionsdescribe supported configuration.OidcStarterBffPoliciesexposes stable policy names for consuming apps.OidcStarterAuthorizationPolicyBuilderExtensionsadds scope/claim policy helpers.OidcStarterAuthenticationPropertiesExtensionsadds the read-onlyAuthenticationProperties.TryGetOidcStarterLoginProviderId(...)accessor for obtaining the OIDC Starter login-provider id persisted in authentication properties.OidcStarterValidatedOidcSignInMetadataandAuthenticationProperties.TryGetOidcStarterValidatedOidcSignInMetadata(...)provide read-only metadata from a successfully validated OIDC sign-in for downstream integrations.IOidcStarterRoleMapperandOidcStarterRoleMappingContextare the role-mapping extension point.ICurrentUserServiceandCurrentUserResponseexpose the current-user contract used by/api/auth/me.
Controllers, low-level validators, and default service implementations exist to support the package endpoints and are not intended as customization points.
Validated sign-in metadata capture requires the standard OpenIdConnectOptions.Events pipeline. If
a consumer configures OpenIdConnectOptions.EventsType, ASP.NET Core resolves that events instance
from DI instead, and OIDC Starter does not capture this metadata for that scheme. OIDC authentication
behavior is otherwise unchanged.
Sample Backend Usage
using OidcStarter.AspNetCore.Bff.Extensions;
builder.Services.AddOidcStarterBff(builder.Configuration);
var app = builder.Build();
app.UseOidcStarterBff();
app.MapControllers();
app.Run();
The sample backend keeps sample-only endpoints such as /api/public/ping in its own project.
Configuration
{
"Starter": {
"FrontendOrigin": "http://localhost:4200",
"DefaultLoginProvider": "oidc",
"AllowedForwardedHosts": [ "localhost" ],
"KnownForwardedProxies": [],
"KnownForwardedNetworks": [],
"SessionLifetime": "08:00:00",
"SlidingExpiration": true,
"CookieSameSite": "None",
"AntiforgeryHeaderName": "X-XSRF-TOKEN",
"AntiforgeryCookieSecurePolicy": "SameAsRequest",
"NameClaimType": "name",
"RoleClaimType": "role",
"AdditionalRoleClaimTypes": [
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"roles"
],
"RequiredScopes": [],
"RequiredClaims": []
},
"Oidc": {
"Authority": "https://identity.example.com/realms/example",
"ClientId": "example-bff",
"ClientSecret": "<secret>",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc",
"RequireHttpsMetadata": true,
"Scopes": [ "openid", "profile", "email" ]
}
}
Starter:DefaultLoginProvider controls the provider challenged by the existing GET /api/auth/login route. It defaults to oidc and must name a registered provider. Leaving it at the default preserves the single-OIDC-consumer flow.
External Login Providers
AddOidcStarterBff(...) registers the built-in OpenID Connect provider with the oidc provider id. Add a social provider only when the consuming host has the required provider credentials and callback registration:
var google = builder.Configuration.GetSection("ExternalLogin:Google");
if (google.GetValue<bool>("Enabled"))
{
builder.Services.AddOidcStarterGoogle(google.GetSection("Options"));
}
var github = builder.Configuration.GetSection("ExternalLogin:GitHub");
if (github.GetValue<bool>("Enabled"))
{
builder.Services.AddOidcStarterGitHub(github.GetSection("Options"));
}
var facebook = builder.Configuration.GetSection("ExternalLogin:Facebook");
if (facebook.GetValue<bool>("Enabled"))
{
builder.Services.AddOidcStarterFacebook(facebook.GetSection("Options"));
}
The package assigns the provider ids google, github, and facebook. The external handler options require provider credentials and accept a local absolute callback path. The default paths are /signin-google, /signin-github, and /signin-facebook; register the matching public HTTPS callback URL with the provider and route that path to the BFF. Do not place client secrets in a browser bundle.
For another handler, configure that authentication scheme in the consuming application, then register its discovery and login metadata separately:
builder.Services.AddOidcStarterLoginProvider(
providerId: "contoso",
displayName: "Contoso",
authenticationScheme: "Contoso");
Provider ids are route-safe lowercase ASCII identifiers. Generic registration does not add or configure the referenced authentication handler.
Provider discovery and login
GET /api/auth/providersreturns the enabled providers withid,displayName,isDefault, and a provider-specificloginUrl.GET /api/auth/loginchallengesStarter:DefaultLoginProvider.GET /api/auth/login/{provider}challenges a registered provider id; an unknown provider returns404.
Existing consumers can continue to call GET /api/auth/login and need not use discovery or provider-targeted login.
Session, logout, and external identity
All registered providers establish the common BFF cookie session. /api/auth/me retains its existing normalized user fields and can add externalIdentity with the provider id plus available emailVerified and pictureUrl fields. Consumers should treat that object as optional.
Logout always clears the local BFF cookie session. The built-in OIDC provider also performs its configured remote sign-out flow. Google, GitHub, Facebook, and generic providers use local-session-only logout; the package does not request remote sign-out from them.
Security And Hosting Notes
The package sets an HTTP-only, secure __Host- session cookie with an 8-hour sliding lifetime by
default. Keep CookieSameSite as None for split-origin local development; production BFF
deployments should usually serve the frontend and backend from one public site and change it to
Lax or Strict where the OIDC provider flow and hosting topology allow it.
Antiforgery Contract
POST /api/auth/logout is protected by a package-local MVC authorization filter that calls
ASP.NET Core IAntiforgery.ValidateRequestAsync. It also checks Origin or Referer against
Starter:FrontendOrigin and the current backend origin. The origin check remains defense in depth;
antiforgery validation is the primary CSRF protection for the package-provided unsafe endpoint.
The antiforgery cookie secure policy defaults to SameAsRequest so local HTTP samples can obtain a
token. Production apps should run behind HTTPS and set Starter:AntiforgeryCookieSecurePolicy to
Always unless their hosting platform has a specific reason not to.
Frontend integration contract:
- Call
GET /api/auth/csrfbefore the first state-changing BFF request, and again whenever the frontend needs to refresh the antiforgery token. - Read the request token from the
XSRF-TOKENcookie. The cookie name can be changed withStarter:AntiforgeryRequestTokenCookieName. - For
fetch, XHR, or AngularHttpClientrequests, send the token in theX-XSRF-TOKENheader. The header name can be changed withStarter:AntiforgeryHeaderName. - For top-level form posts such as OIDC logout navigation, send the same token in the ASP.NET Core
antiforgery form field named
__RequestVerificationToken. - Treat every cookie-authenticated BFF request that changes server-side or identity-provider state
as state-changing. In this package today that means
POST /api/auth/logout; custom endpoints added by consuming apps should follow the same rule forPOST,PUT,PATCH, andDELETE.
Compatibility note: package-provided unsafe BFF endpoints always require antiforgery validation.
Starter:RequireAntiforgeryToken is obsolete and retained only for compatibility with existing
configuration. It no longer controls package-provided endpoints. Custom frontends must call
GET /api/auth/csrf and submit the token for logout and other state-changing BFF requests.
Any custom frontend or third-party frontend integrating with this backend package must implement this contract before calling package-provided or app-defined state-changing BFF endpoints.
Authorization Foundation
The package configures ASP.NET Core authorization and exposes a small policy foundation rather than a custom RBAC framework.
Defaults:
Starter:NameClaimTypedefaults tonameand is used for OIDC token validation and/api/auth/me.Starter:RoleClaimTypedefaults toroleand is used by ASP.NET Core role authorization, including[Authorize(Roles = "...")].Starter:AdditionalRoleClaimTypesdefaults to the ASP.NET Core role claim URI androles; these extra claim types are included in therolesarray returned by/api/auth/me.IOidcStarterRoleMapperhas a built-in flat-claim implementation that reads those configured role claim types.- The package registers
OidcStarterBffPolicies.AuthenticatedUser, a named policy that only requires a valid authenticated backend session.
Optional configured policies:
- Set
Starter:RequiredScopesto addOidcStarterBffPolicies.ConfiguredRequiredScopes. The policy requires all configured scopes and checks bothscopeandscpclaims. - Set
Starter:RequiredClaimsto addOidcStarterBffPolicies.ConfiguredRequiredClaims. Each entry requires the claim type to exist; whenValuesare supplied, at least one matching value must be present.
Example:
{
"Starter": {
"RoleClaimType": "roles",
"RequiredScopes": [ "profile" ],
"RequiredClaims": [
{ "Type": "tenant", "Values": [ "academy" ] }
]
}
}
using Microsoft.AspNetCore.Authorization;
using OidcStarter.AspNetCore.Bff.Authorization;
[Authorize(Policy = OidcStarterBffPolicies.AuthenticatedUser)]
[HttpGet("/api/protected/ping")]
public IActionResult Ping() => Ok();
Consuming applications still own their business authorization model: application roles, tenant membership, resource ownership, and domain-specific policies should be defined in the consuming app.
Custom Role Mapping
Different OIDC providers represent roles differently. The package handles flat role claims by
default, but it does not hardcode provider-specific nested structures. If a provider emits roles in
custom or nested claims, add an IOidcStarterRoleMapper implementation in the consuming app. The
mapper receives the current principal and, during OIDC ticket creation, the saved backend
access_token when one is available:
using OidcStarter.AspNetCore.Bff.Authorization;
internal sealed class MyProviderRoleMapper : IOidcStarterRoleMapper
{
public IEnumerable<string> GetRoles(OidcStarterRoleMappingContext context)
{
// Extract provider-specific roles from context.Principal or context.AccessToken.
yield return "example-role";
}
}
Register it before or after AddOidcStarterBff:
builder.Services.AddOidcStarterRoleMapper<MyProviderRoleMapper>();
builder.Services.AddOidcStarterBff(builder.Configuration);
Mapped roles are additive. The default flat-claim mapper remains active, and custom mapper output is
deduplicated for /api/auth/me. The package also copies mapped roles into the configured
Starter:RoleClaimType through claims transformation, so ASP.NET Core role checks can use the same
normalized role names.
The sample backend demonstrates this extension point with a Keycloak-specific mapper that reads the
backend access_token and extracts roles from realm_access.roles and
resource_access.{client}.roles. It filters offline_access, uma_authorization, and
default-roles-* as sample noise, but otherwise leaves realm and client roles visible. That logic
intentionally lives in the sample app, not in the reusable package.
UseOidcStarterBff() applies forwarded headers before HTTPS redirection. AllowedForwardedHosts
limits accepted X-Forwarded-Host values. In production, also set KnownForwardedProxies to trusted
proxy IP addresses or KnownForwardedNetworks to trusted CIDR ranges such as 10.0.0.0/8; do not
trust arbitrary forwarded headers from the public internet.
Release Readiness Notes
The package provides a backward-compatible BFF API. Default role mapping still reads flat role claims, and provider-specific role extraction remains app-owned.
Integration requirements consumers should know before enabling production settings:
- Configure
Oidcwith a confidential OIDC client suitable for server-side login. - Set
Starter:FrontendOriginto the trusted frontend origin. - Implement the antiforgery contract before calling state-changing BFF endpoints such as
POST /api/auth/logout. - Configure forwarded headers with trusted hosts/proxies when running behind a reverse proxy.
- Normalize provider-specific roles with
IOidcStarterRoleMapperwhen the provider does not emit flat role claims. - Move secrets out of checked-in appsettings files for real deployments.
POST /api/auth/logout requires antiforgery validation. Custom frontends must first obtain a token
from GET /api/auth/csrf and submit it with logout requests. The legacy
Starter:RequireAntiforgeryToken setting remains for compatibility but does not control protection
for package-provided endpoints.
The current backend package release is 1.2.1. Release 1.2.0 introduced the additive read-only
AuthenticationProperties.TryGetOidcStarterLoginProviderId(...) accessor. Release 1.2.1 was a
metadata-only correction to the NuGet Project Website; these releases introduced no login/logout
runtime behavior changes.
Local Packaging
From the repository root:
dotnet build .\src\OidcStarter.AspNetCore.Bff\OidcStarter.AspNetCore.Bff.csproj -c Release
dotnet pack .\src\OidcStarter.AspNetCore.Bff\OidcStarter.AspNetCore.Bff.csproj -c Release --no-build
The package is written to src/OidcStarter.AspNetCore.Bff/bin/Release.
Publication command for maintainers:
dotnet nuget push .\src\OidcStarter.AspNetCore.Bff\bin\Release\OidcStarter.AspNetCore.Bff.<VERSION>.nupkg --api-key <NUGET_API_KEY> --source https://api.nuget.org/v3/index.json
Only publish after confirming the target version, release notes, and registry credentials.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- AspNet.Security.OAuth.GitHub (>= 9.4.1)
- Microsoft.AspNetCore.Authentication.Facebook (>= 9.0.4)
- Microsoft.AspNetCore.Authentication.Google (>= 9.0.4)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 9.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.