Skip to content

Instantly share code, notes, and snippets.

@jmeline
Last active June 29, 2021 21:50
Show Gist options
  • Save jmeline/756728448fc5efb1ecc07832c3566eb4 to your computer and use it in GitHub Desktop.
Save jmeline/756728448fc5efb1ecc07832c3566eb4 to your computer and use it in GitHub Desktop.
Dotnet - Authentication - How to do an Auth0 Redirect
namespace CarrierOnboarding.Mfe.Infrastructure
{
public static class AuthenticationExtensions
{
public static AuthenticationBuilder AddMktpCookieAuthentication(this IServiceCollection services)
{
void DefaultOptions(AuthenticationOptions options)
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}
void DefaultCookieOptions(CookieAuthenticationOptions options)
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.SlidingExpiration = true;
options.LoginPath = "/";
options.Events = new CookieAuthenticationEvents
{
OnRedirectToAccessDenied = context =>
{
// prevent redirect on access denied in the api.
// Without this, a 404 would be returned because the RedirectUri comes from the cookie ("/Account/AccessDenied"),
// but we have no such endpoint
if (context.Request.Path.StartsWithSegments("/api", StringComparison.CurrentCultureIgnoreCase))
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return Task.CompletedTask;
},
// How to redirect back to the top level site from carrier onboarding
OnRedirectToLogin = context =>
{
// Keep everything else in the automatically generated URL; just replace the
// path portion so that the LoginPath becomes root-relative instead of relative
// to the PathBase.
if (!context.Request.Headers.TryGetValue("x-original-host", out var originalHost))
return Task.CompletedTask;
var redirectUrl =
$"https://{originalHost}/?ReturnUrl=/carrieronboarding";
context.Response.Redirect(redirectUrl);
return Task.CompletedTask;
}
};
}
return services
.AddAuthentication(DefaultOptions)
.AddCookie(DefaultCookieOptions);
}
}
}
public class AuthenticationMiddleware
{
private readonly RequestDelegate _next;
public AuthenticationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.StartsWithSegments(new PathString("/health")))
{
await _next(context);
}
if (!context.Response.HasStarted)
{
if (context.User.Identity.IsAuthenticated)
{
// Check to see if our access token has expired and ask the user to re-authenticate if so
// This check effectively limits the SlidingExpiration setting of the cookie authentication
var expiresAt = DateTimeOffset.Parse(await context.GetTokenAsync("expires_at"));
if (expiresAt > DateTimeOffset.Now)
{
await _next(context);
}
else
{
await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme); // "Cookies" instead of "Auth0"
}
}
else
{
await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
}
/*
Middleware to be used in top level site
Plan.oading
carrier onboarding
In order to redirect from carrier onboarding back to plan loading, I add in the following middleware
*/
public class AuthenticationMiddleware
{
private readonly RequestDelegate _next;
public AuthenticationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.StartsWithSegments(new PathString("/health")))
{
await _next(context);
}
if (!context.Response.HasStarted)
{
if (context.User.Identity.IsAuthenticated)
{
// Check to see if our access token has expired and ask the user to re-authenticate if so
// This check effectively limits the SlidingExpiration setting of the cookie authentication
var expiresAt = DateTimeOffset.Parse(await context.GetTokenAsync("expires_at"));
if (expiresAt > DateTimeOffset.Now)
{
await _next(context);
}
else
{
await ChallengeAuth0(context);
}
}
else
{
await ChallengeAuth0(context);
}
}
}
private static async Task ChallengeAuth0(HttpContext context)
{
var authenticationProperties = context.Request.Query.ContainsKey("ReturnUrl")
? new AuthenticationProperties {RedirectUri = context.Request.Query["ReturnUrl"]}
: null;
await context.ChallengeAsync("Auth0", authenticationProperties);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment