public MultipleAuthenticationStartup(ClaimsPrincipal principal1, ClaimsPrincipal principal2, bool automaticAuthenticate, ScopeValidationOptions options)
 {
     _principal1 = principal1;
     _principal2 = principal2;
     _scopeOptions = options;
     _automaticAuthenticate = automaticAuthenticate;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ScopeValidationMiddleware"/> class.
        /// </summary>
        /// <param name="next">The next midleware.</param>
        /// <param name="scopes">The scopes.</param>
        public ScopeValidationMiddleware(RequestDelegate next, ScopeValidationOptions options)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (string.IsNullOrWhiteSpace(options.ScopeClaimType))
            {
                throw new ArgumentNullException(nameof(options.ScopeClaimType));
            }

            if (options.AllowedScopes == null)
            {
                throw new ArgumentNullException(nameof(options.AllowedScopes));
            }

            _next = next;
            _options = options;
        }
        public static IApplicationBuilder AllowScopes(this IApplicationBuilder app, params string[] scopes)
        {
            var options = new ScopeValidationOptions
            {
                AllowedScopes = scopes
            };

            return app.AllowScopes(options);
        }
        public static IApplicationBuilder UseIdentityServerAuthentication(this IApplicationBuilder app, IdentityServerAuthenticationOptions options)
        {
            var combinedOptions = new CombinedAuthenticationOptions();
            combinedOptions.TokenRetriever = options.TokenRetriever;
            combinedOptions.AuthenticationScheme = options.AuthenticationScheme;
            
            switch (options.SupportedTokens)
            {
                case SupportedTokens.Jwt:
                    combinedOptions.JwtBearerOptions = ConfigureJwt(options);
                    break;
                case SupportedTokens.Reference:
                    combinedOptions.IntrospectionOptions = ConfigureIntrospection(options);
                    break;
                case SupportedTokens.Both:
                    combinedOptions.JwtBearerOptions = ConfigureJwt(options);
                    combinedOptions.IntrospectionOptions = ConfigureIntrospection(options);
                    break;
                default:
                    throw new Exception("SupportedTokens has invalid value");
            }

            app.UseMiddleware<IdentityServerAuthenticationMiddleware>(app, combinedOptions);

            var allowedScopes = new List<string>();
            if (!string.IsNullOrWhiteSpace(options.ScopeName))
            {
                allowedScopes.Add(options.ScopeName);
            }

            if (options.AdditionalScopes != null && options.AdditionalScopes.Any())
            {
                allowedScopes.AddRange(options.AdditionalScopes);
            }

            if (allowedScopes.Any())
            {
                var scopeOptions = new ScopeValidationOptions
                {
                    AllowedScopes = allowedScopes,
                    AuthenticationScheme = options.AuthenticationScheme
                };

                app.AllowScopes(scopeOptions);
            }

            return app;
        }
        //[Fact]
        //public async Task Authenticated_User_Missing_Scopes_Should_Be_Forbidden()
        //{
        //    var principal = Principal.Create("custom",
        //        new Claim("sub", "123"));
        //    var allowedScopes = new[] { "scope1", "scope2" };

        //    var client = CreateClient(principal, allowedScopes);
        //    var response = await client.GetAsync("/");

        //    response.StatusCode.Should().Be(HttpStatusCode.Forbidden);
        //}

        //[Fact]
        //public async Task Authenticated_User_Matching_Scope_Should_Be_Allowed()
        //{
        //    var principal = Principal.Create("custom",
        //        new Claim("sub", "123"),
        //        new Claim("scope", "scope1"));
        //    var allowedScopes = new[] { "scope1", "scope2" };

        //    var client = CreateClient(principal, allowedScopes);
        //    var response = await client.GetAsync("/");

        //    response.StatusCode.Should().Be(HttpStatusCode.OK);
        //}

        private HttpClient CreateClient(ClaimsPrincipal principal1, ClaimsPrincipal principal2, bool automaticAuthenticate, IEnumerable<string> allowedScopes, string scopeAuthenticationScheme)
        {
            var options = new ScopeValidationOptions
            {
                AllowedScopes = allowedScopes,
                AuthenticationScheme = scopeAuthenticationScheme
            };

            var startup = new MultipleAuthenticationStartup(principal1, principal2, automaticAuthenticate, options);
            var server = TestServer.Create(null, startup.Configure, startup.ConfigureServices);

            return server.CreateClient();
        }
 public static IApplicationBuilder AllowScopes(this IApplicationBuilder app, ScopeValidationOptions options)
 {
     return app.UseMiddleware<ScopeValidationMiddleware>(options);
 }