private void SetTokenCookies(String accessToken, SecurityToken token, String refreshToken) { //There is no end to the pain of trying to get this right, fix the path here to ensure its correct. var cookiePath = CookieUtils.FixPath(Options.CookiePath); var expires = Options.StoreCookiesInSession ? default(DateTimeOffset?) : token.ValidTo; cookieManager.AppendResponseCookie(Context, BearerCookieName, accessToken, new CookieOptions() { Secure = true, HttpOnly = Options.BearerHttpOnly, Path = cookiePath, Expires = expires, SameSite = Options.SameSite }); cookieManager.AppendResponseCookie(Context, RefreshCookieName, refreshToken, new CookieOptions() { Secure = true, HttpOnly = Options.RefreshHttpOnly, Path = cookiePath, Expires = expires, SameSite = Options.SameSite }); }
private void EraseCookies() { //There is no end to the pain of trying to get this right, fix the path here to ensure its correct. var cookiePath = CookieUtils.FixPath(Options.CookiePath); cookieManager.DeleteCookie(Context, BearerCookieName, new CookieOptions() { Secure = true, HttpOnly = Options.BearerHttpOnly, Path = cookiePath }); cookieManager.DeleteCookie(Context, RefreshCookieName, new CookieOptions() { Secure = true, HttpOnly = Options.RefreshHttpOnly, Path = cookiePath }); }
public void PostConfigure(string name, JwtCookieAuthenticationOptions options) { if (String.IsNullOrEmpty(options.ClientId)) { throw new ArgumentException("You must provide a client id in the options."); } if (String.IsNullOrEmpty(options.MetadataPath)) { throw new ArgumentException("You must provide a metadata path in the options."); } if (String.IsNullOrEmpty(options.Authority)) { throw new ArgumentException("You must provide an authority in the options."); } if (String.IsNullOrEmpty(options.ChallengeScheme)) { throw new ArgumentException("You must provide an ChallengeScheme in the options."); } options.CookiePath = CookieUtils.FixPath(options.CookiePath); }
private static IdServerAuthOptions options; //Probably not the best idea to have this state, but this makes this way easier to use. /// <summary> /// Configure the services for id server authentication according to the convention established. There are 2 major roles an application can fulfill. /// The first is to act as a client, which means it has razor views that should be returned This will use jwts in cookies. /// The other is as an api, which means it has controllers that return data. This will use jwts in bearer headers. /// An application can be both of these roles at once. /// </summary> /// <param name="services"></param> /// <param name="optionsBuilder"></param> /// <returns></returns> public static IServiceCollection AddConventionalIdServerAuthentication(this IServiceCollection services, Action <IdServerAuthOptions> optionsBuilder) { if (optionsBuilder == null) { throw new InvalidOperationException("You must include an options builder"); } options = new IdServerAuthOptions(); optionsBuilder.Invoke(options); options.CookiePath = CookieUtils.FixPath(options.CookiePath); if (options.AppOptions == null) { throw new InvalidOperationException("You must provide the application specific options."); } if (String.IsNullOrEmpty(options.AppOptions.Authority)) { throw new InvalidOperationException("You must provide an Authority (the url of the id server) in the options."); } if (String.IsNullOrEmpty(options.AppOptions.Scope)) { throw new InvalidOperationException("You must provide a scope for the app."); } if (options.ActAsClient) { if (String.IsNullOrEmpty(options.AppOptions.ClientId)) { throw new InvalidOperationException("You must provide a client id for the app to use it as a client."); } } var authBuilder = services.AddAuthentication(o => { if (options.ActAsClient) { o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; } //If the user provides a default scheme, override it here, leave this last so it will always override. if (options.DefaultScheme != null) { o.DefaultScheme = options.DefaultScheme; } }); services.AddThreaxSharedHttpClient(); if (options.ActAsClient) { authBuilder.AddJwtCookie(AuthCoreSchemes.Cookies, o => { o.Authority = options.AppOptions.Authority; o.ClientId = options.AppOptions.ClientId; o.ClientSecret = options.AppOptions.ClientSecret; o.CookiePath = options.CookiePath; o.ChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; o.AccessDeniedPath = options.AccessDeniedPath; o.ValidateAudience = true; o.ValidAudiences = new String[] { options.AppOptions.Scope }; o.ValidateLifetime = true; o.ClockSkew = options.ClockSkew; o.Events = new JwtCookieEvents() { OnValidatePrincipal = c => c.BuildUserWithRequestServices() }; options.CustomizeCookies?.Invoke(o); }) .AddOpenIdConnect(o => { o.SignInScheme = AuthCoreSchemes.Cookies; o.Authority = options.AppOptions.Authority; o.ClientSecret = options.AppOptions.ClientSecret; o.ClientId = options.AppOptions.ClientId; o.ResponseType = "code id_token"; o.SaveTokens = true; o.UseTokenLifetime = true; o.GetClaimsFromUserInfoEndpoint = false; o.CallbackPath = options.CallbackPath; o.SignedOutCallbackPath = options.SignedOutCallbackPath; o.RemoteSignOutPath = options.RemoteSignOutPath; o.SignedOutRedirectUri = options.SignedOutRedirectUri; o.TokenValidationParameters.ValidAudiences = new String[] { options.AppOptions.Scope }; o.TokenValidationParameters.ValidateAudience = true; o.Scope.Clear(); o.Scope.Add("openid"); o.Scope.Add("profile"); o.Scope.Add("offline_access"); o.Scope.Add(options.AppOptions.Scope); if (options.AppOptions.AdditionalScopes != null) { foreach (var scope in options.AppOptions.AdditionalScopes) { o.Scope.Add(scope); } } o.Events.OnSignedOutCallbackRedirect = async c => { //When signed out endpoint is called, sign out of cookie auth await c.HttpContext.SignOutAsync(JwtCookieAuthenticationDefaults.AuthenticationScheme); }; options.CustomizeOpenIdConnect?.Invoke(o); }); } if (options.ActAsApi) { var bearerEvents = new JwtBearerAuthenticationEvents(Microsoft.IdentityModel.Tokens.SecurityAlgorithms.RsaSha256, options.ClockSkew) { OnAuthorizeUser = c => c.BuildUserWithRequestServices() }; authBuilder.AddJwtBearer(AuthCoreSchemes.Bearer, o => { o.Authority = options.AppOptions.Authority; o.RequireHttpsMetadata = true; o.Audience = options.AppOptions.Scope; o.Events = new JwtBearerEvents() { OnTokenValidated = bearerEvents.TokenValidated, OnMessageReceived = s => { s.Token = s.HttpContext.Request.Headers["bearer"]; return(System.Threading.Tasks.Task.FromResult(0)); } }; options.CustomizeBearer?.Invoke(o); }); } return(services); }