// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services .AddFluentSpotifyClient() .ConfigureHttpClientBuilder(b => b.AddSpotifyAuthorizationCodeFlow(spotifyAuthenticationScheme: SpotifyAuthenticationScheme)); services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie( o => { o.LoginPath = new PathString("/login"); o.LogoutPath = new PathString("/logout"); // Validate claims and tokens that are required when using FluentSpotifyClient. o.Events.OnSigningIn = c => { if (!SpotifyRequiredClaimsUtils.Validate(c.Principal)) { throw new InvalidOperationException("User ID was not provided during login. Ensure that NameIdentifier claim is added to SpotifyOptions."); } if (!SpotifyRequiredTokensUtils.Validate(c.Properties)) { throw new InvalidOperationException("Tokens were not provided during login. Ensure that SaveTokens is set to true in SpotifyOptions."); } return(Task.CompletedTask); }; o.Events.OnValidatePrincipal = async c => { if (!SpotifyRequiredClaimsUtils.Validate(c.Principal) || !SpotifyRequiredTokensUtils.Validate(c.Properties)) { c.RejectPrincipal(); await c.HttpContext.SignOutAsync(); c.HttpContext.Response.Redirect("/login"); } }; }) .AddSpotify( SpotifyAuthenticationScheme, o => { var spotifyAuthSection = this.Configuration.GetSection("Authentication:Spotify"); o.ClientId = spotifyAuthSection["ClientId"]; o.ClientSecret = spotifyAuthSection["ClientSecret"]; // Uncomment to add email claim. Requires user-read-email scope. ////o.ClaimActions.MapJsonKey(ClaimTypes.Email, "email"); ////o.Scope.Add(SpotifyScopes.UserReadEmail); // Uncomment to add custom profile picture claim. ////o.ClaimActions.MapCustomJson( //// "urn:spotify:profilepicture", //// e => e.TryGetProperty("images", out var images) && images.GetArrayLength() > 0 && images[0].TryGetProperty("url", out var url) ? url.GetString() : null); o.Scope.Add(SpotifyScopes.PlaylistReadPrivate); o.Scope.Add(SpotifyScopes.PlaylistReadCollaborative); o.SaveTokens = true; }); services .AddControllersWithViews(); }