Welcome to the navigation

Est esse in commodo mollit non anim consectetur proident, in elit, tempor sit id officia cillum pariatur, ut enim veniam, ea aliquip deserunt incididunt reprehenderit. Est labore anim duis ut tempor deserunt sit voluptate minim exercitation cupidatat laborum, amet, qui ullamco quis dolore ut aliquip nostrud elit, occaecat eiusmod dolor

Yeah, this will be replaced... But please enjoy the search!

Speeding Up Local Development with a Fake OpenID Authentication Handler

Setting up OpenID authentication can be painful in development environments – especially when the identity server isn’t publicly accessible or you’re still waiting on client configuration.

To solve this, we created a local authentication scheme that behaves like OpenID but doesn’t require any network connection or external setup. It lets developers instantly sign in as a fake user with predefined roles – perfect for local testing and remote development.

Here’s the simplified implementation:

// usings
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

internal class LocalAuthenticationSchemeOptions : AuthenticationSchemeOptions { }

internal class LocalAuthenticationSchemeHandler(
    IOptionsMonitor options,
    ILoggerFactory logger,
    UrlEncoder encoder)
    : AuthenticationHandler(options, logger, encoder)
{
    protected override async Task HandleAuthenticateAsync()
    {
        var claims = new[]
        {
            // add any claim you need, these are for Optimizely CMS
            new Claim(ClaimTypes.Role, "Admins"),
            new Claim(ClaimTypes.Role, "CmsAdmins"),
            new Claim(ClaimTypes.Role, "CmsEditors"),
            new Claim(ClaimTypes.Name, "John Doe")
        };

        var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Local"));
        var ticket = new AuthenticationTicket(principal, Scheme.Name);

        return await Task.FromResult(AuthenticateResult.Success(ticket));
    }
}

For Optimizely you'll need to ensure that the claims added correspond with what configs you have in you appsettings, see https://docs.developers.optimizely.com/content-management-system/docs/virtual-roles.

And we wire it up conditionally during startup:

if (environment.IsDevelopment())
{
    services.AddAuthentication("LocalAuthentication")
        .AddScheme<LocalAuthenticationSchemeOptions, LocalAuthenticationSchemeHandler>(
            "LocalAuthentication",
            opts => { });
}
else
{
    // Your OpenID-implementation, may be services.AddAuthentication...
    services.AddOpenIdServicesConfiguration(configuration, logger);
}

This setup means:

  • Local devs can log in instantly, without OpenID.

  • Full control over user identity and roles — test as any role.

  • No dependency on external servers, making remote/offline dev possible.

  • Production remains secure, since the handler is only active in Development mode.

It’s a small addition, but it dramatically simplifies authentication workflows during development. Instead of waiting for OpenID configuration or tunneling into internal networks, developers can jump straight into building features.