예제 #1
0
        public async Task CustomHandlersAuthenticateRunsClaimsTransformationEveryTime()
        {
            var transform = new RunOnce();
            var services  = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
            {
                o.AddScheme <BaseHandler>("base", "whatever");
            })
                            .AddSingleton <IClaimsTransformation>(transform)
                            .BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = services;

            // Because base handler returns a different principal per call, its run multiple times
            await context.AuthenticateAsync("base");

            Assert.Equal(1, transform.Ran);

            await context.AuthenticateAsync("base");

            Assert.Equal(2, transform.Ran);

            await context.AuthenticateAsync("base");

            Assert.Equal(3, transform.Ran);
        }
예제 #2
0
        public async Task NullForwardSelectorUsesDefault()
        {
            var services = new ServiceCollection().AddLogging();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme = MicrosoftAccountDefaults.AuthenticationScheme;
                o.AddScheme <TestHandler2>("auth1", "auth1");
                o.AddScheme <TestHandler3>("selector", "selector");
                o.AddScheme <TestHandler>("specific", "specific");
            })
            .AddMicrosoftAccount(o =>
            {
                ConfigureDefaults(o);
                o.ForwardDefault         = "auth1";
                o.ForwardDefaultSelector = _ => null;
            });

            var specific = new TestHandler();

            services.AddSingleton(specific);
            var forwardDefault = new TestHandler2();

            services.AddSingleton(forwardDefault);
            var selector = new TestHandler3();

            services.AddSingleton(selector);

            var sp      = services.BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = sp;

            await context.AuthenticateAsync();

            Assert.Equal(1, forwardDefault.AuthenticateCount);

            await context.ForbidAsync();

            Assert.Equal(1, forwardDefault.ForbidCount);

            await context.ChallengeAsync();

            Assert.Equal(1, forwardDefault.ChallengeCount);

            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync());

            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync(new ClaimsPrincipal()));

            Assert.Equal(0, selector.AuthenticateCount);
            Assert.Equal(0, selector.ForbidCount);
            Assert.Equal(0, selector.ChallengeCount);
            Assert.Equal(0, selector.SignInCount);
            Assert.Equal(0, selector.SignOutCount);
            Assert.Equal(0, specific.AuthenticateCount);
            Assert.Equal(0, specific.ForbidCount);
            Assert.Equal(0, specific.ChallengeCount);
            Assert.Equal(0, specific.SignInCount);
            Assert.Equal(0, specific.SignOutCount);
        }
예제 #3
0
        public async Task AuthenticateThrowsForSchemeMismatch()
        {
            var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
            {
                o.AddScheme <BaseHandler>("base", "whatever");
            }).BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = services;

            await context.AuthenticateAsync("base");

            var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => context.AuthenticateAsync("missing"));

            Assert.Contains("base", ex.Message);
        }
        public static DefaultHttpContext GetHttpContextAuthenticated
        (
            string authenticationType,

            List <Claim> claims
        )
        {
            var context = new DefaultHttpContext
            {
                User = new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType))
            };

            var services = new ServiceCollection();

            services.AddAuthentication(authenticationType);

            var application = new ApplicationBuilder(services.BuildServiceProvider());

            application.Use(async(context, next) =>
            {
                await context.AuthenticateAsync(authenticationType).ConfigureAwait(false);

                await next().ConfigureAwait(false);
            });

            return(context);
        }
예제 #5
0
        public async Task AuthenticateAsync_WithToken_PerformsAuthentication_Using_ContainerEncryptionKey_If_WebSiteAuthEncryptionKey_Not_Available()
        {
            var containerEncryptionKeyBytes = TestHelpers.GenerateKeyBytes();

            var vars = new Dictionary <string, string>
            {
                { EnvironmentSettingNames.WebSiteAuthEncryptionKey, string.Empty },
                { EnvironmentSettingNames.ContainerEncryptionKey, TestHelpers.GenerateKeyHexString(containerEncryptionKeyBytes) }
            };

            using (var env = new TestScopedEnvironmentVariable(vars))
            {
                // Arrange
                DefaultHttpContext context = GetContext();

                string token = SimpleWebTokenHelper.CreateToken(DateTime.UtcNow.AddMinutes(2), containerEncryptionKeyBytes);
                context.Request.Headers.Add(ArmAuthenticationHandler.ArmTokenHeaderName, token);

                // Act
                AuthenticateResult result = await context.AuthenticateAsync();

                // Assert
                Assert.True(result.Succeeded);
                Assert.True(result.Principal.Identity.IsAuthenticated);
                Assert.True(result.Principal.HasClaim(SecurityConstants.AuthLevelClaimType, AuthorizationLevel.Admin.ToString()));
            }
        }
예제 #6
0
    public async Task ForwardAuthenticateOnlyRunsTransformOnceByDefault()
    {
        var services  = new ServiceCollection().AddLogging();
        var transform = new RunOnce();
        var builder   = services.AddSingleton <IClaimsTransformation>(transform).AddAuthentication(o =>
        {
            o.DefaultScheme = DefaultScheme;
            o.AddScheme <TestHandler2>("auth1", "auth1");
            o.AddScheme <TestHandler>("specific", "specific");
        });

        RegisterAuth(builder, o =>
        {
            o.ForwardDefault      = "auth1";
            o.ForwardAuthenticate = "specific";
        });

        var specific = new TestHandler();

        services.AddSingleton(specific);
        var forwardDefault = new TestHandler2();

        services.AddSingleton(forwardDefault);

        var sp      = services.BuildServiceProvider();
        var context = new DefaultHttpContext();

        context.RequestServices = sp;

        await context.AuthenticateAsync();

        Assert.Equal(1, transform.Ran);
    }
예제 #7
0
        public async Task VirtualSchemeTargetsForwardWithDefaultTarget()
        {
            var services = new ServiceCollection().AddOptions().AddLogging();

            services.AddAuthentication(o =>
            {
                o.AddScheme <TestHandler>("auth1", "auth1");
                o.AddScheme <TestHandler2>("auth2", "auth2");
            })
            .AddPolicyScheme("forward", "forward", p => p.ForwardDefault = "auth1");

            var handler1 = new TestHandler();

            services.AddSingleton(handler1);
            var handler2 = new TestHandler2();

            services.AddSingleton(handler2);

            var sp      = services.BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = sp;

            Assert.Equal(0, handler1.AuthenticateCount);
            Assert.Equal(0, handler1.ForbidCount);
            Assert.Equal(0, handler1.ChallengeCount);
            Assert.Equal(0, handler1.SignInCount);
            Assert.Equal(0, handler1.SignOutCount);
            Assert.Equal(0, handler2.AuthenticateCount);
            Assert.Equal(0, handler2.ForbidCount);
            Assert.Equal(0, handler2.ChallengeCount);
            Assert.Equal(0, handler2.SignInCount);
            Assert.Equal(0, handler2.SignOutCount);

            await context.AuthenticateAsync("forward");

            Assert.Equal(1, handler1.AuthenticateCount);
            Assert.Equal(0, handler2.AuthenticateCount);

            await context.ForbidAsync("forward");

            Assert.Equal(1, handler1.ForbidCount);
            Assert.Equal(0, handler2.ForbidCount);

            await context.ChallengeAsync("forward");

            Assert.Equal(1, handler1.ChallengeCount);
            Assert.Equal(0, handler2.ChallengeCount);

            await context.SignOutAsync("forward");

            Assert.Equal(1, handler1.SignOutCount);
            Assert.Equal(0, handler2.SignOutCount);

            await context.SignInAsync("forward", new ClaimsPrincipal());

            Assert.Equal(1, handler1.SignInCount);
            Assert.Equal(0, handler2.SignInCount);
        }
예제 #8
0
        public async Task AuthenticateAsync_WithoutToken_DoesNotAuthenticate()
        {
            // Arrange
            DefaultHttpContext context = GetContext();

            // Act
            AuthenticateResult result = await context.AuthenticateAsync();

            // Assert
            Assert.True(result.None);
            Assert.Null(result.Failure);
            Assert.Null(result.Principal);
        }
예제 #9
0
        public async Task CanForwardDefault()
        {
            var services = new ServiceCollection().AddLogging();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme = OpenIdConnectDefaults.AuthenticationScheme;
                o.AddScheme <TestHandler>("auth1", "auth1");
            })
            .AddOpenIdConnect(o =>
            {
                ConfigureDefaults(o);
                o.ForwardDefault = "auth1";
            });

            var forwardDefault = new TestHandler();

            services.AddSingleton(forwardDefault);

            var sp      = services.BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = sp;

            Assert.Equal(0, forwardDefault.AuthenticateCount);
            Assert.Equal(0, forwardDefault.ForbidCount);
            Assert.Equal(0, forwardDefault.ChallengeCount);
            Assert.Equal(0, forwardDefault.SignInCount);
            Assert.Equal(0, forwardDefault.SignOutCount);

            await context.AuthenticateAsync();

            Assert.Equal(1, forwardDefault.AuthenticateCount);

            await context.ForbidAsync();

            Assert.Equal(1, forwardDefault.ForbidCount);

            await context.ChallengeAsync();

            Assert.Equal(1, forwardDefault.ChallengeCount);

            await context.SignOutAsync();

            Assert.Equal(1, forwardDefault.SignOutCount);

            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync(new ClaimsPrincipal()));
        }
예제 #10
0
        public async Task AuthenticateAsync_WithExpiredToken_FailsAuthentication()
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.GenerateKeyHexString()))
            {
                DefaultHttpContext context = GetContext();

                string token = SimpleWebTokenHelper.CreateToken(DateTime.UtcNow.AddMinutes(-20));
                context.Request.Headers.Add(ArmAuthenticationHandler.ArmTokenHeaderName, token);

                // Act
                AuthenticateResult result = await context.AuthenticateAsync();

                // Assert
                Assert.False(result.Succeeded);
                Assert.NotNull(result.Failure);
                Assert.Null(result.Principal);
            }
        }
예제 #11
0
        public async Task ForwardAuthenticateWinsOverDefault()
        {
            var services = new ServiceCollection().AddLogging();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme       = "default";
                o.DefaultSignInScheme = "auth1";
                o.AddScheme <TestHandler2>("auth1", "auth1");
                o.AddScheme <TestHandler>("specific", "specific");
            })
            .AddOAuth("default", o =>
            {
                ConfigureDefaults(o);
                o.ForwardDefault      = "auth1";
                o.ForwardAuthenticate = "specific";
            });

            var specific = new TestHandler();

            services.AddSingleton(specific);
            var forwardDefault = new TestHandler2();

            services.AddSingleton(forwardDefault);

            var sp      = services.BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = sp;

            await context.AuthenticateAsync();

            Assert.Equal(0, specific.SignOutCount);
            Assert.Equal(1, specific.AuthenticateCount);
            Assert.Equal(0, specific.ForbidCount);
            Assert.Equal(0, specific.ChallengeCount);
            Assert.Equal(0, specific.SignInCount);

            Assert.Equal(0, forwardDefault.AuthenticateCount);
            Assert.Equal(0, forwardDefault.ForbidCount);
            Assert.Equal(0, forwardDefault.ChallengeCount);
            Assert.Equal(0, forwardDefault.SignInCount);
            Assert.Equal(0, forwardDefault.SignOutCount);
        }
예제 #12
0
        public async Task AuthenticateAsync_WithToken_PerformsAuthentication()
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.GenerateKeyHexString()))
            {
                // Arrange
                DefaultHttpContext context = GetContext();

                string token = SimpleWebTokenHelper.CreateToken(DateTime.UtcNow.AddMinutes(2));
                context.Request.Headers.Add(ArmAuthenticationHandler.ArmTokenHeaderName, token);

                // Act
                AuthenticateResult result = await context.AuthenticateAsync();

                // Assert
                Assert.True(result.Succeeded);
                Assert.True(result.Principal.Identity.IsAuthenticated);
                Assert.True(result.Principal.HasClaim(SecurityConstants.AuthLevelClaimType, AuthorizationLevel.Admin.ToString()));
            }
        }
예제 #13
0
        public async Task AuthenticateAsync_WithInvalidToken_FailsAuthentication()
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.GenerateKeyHexString()))
            {
                // Arrange
                DefaultHttpContext context = GetContext();

                string token = SimpleWebTokenHelper.CreateToken(DateTime.UtcNow.AddMinutes(2));
                token = token.Substring(0, token.Length - 5);
                context.Request.Headers.Add(ScriptConstants.SiteTokenHeaderName, token);

                // Act
                AuthenticateResult result = await context.AuthenticateAsync();

                // Assert
                Assert.False(result.Succeeded);
                Assert.NotNull(result.Failure);
                Assert.Null(result.Principal);
            }
        }
        public async Task ServicesWithDefaultIAuthenticationHandlerMethodsTest()
        {
            var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
            {
                o.AddScheme <BaseHandler>("base", "whatever");
                o.DefaultScheme = "base";
            }).BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = services;

            await context.AuthenticateAsync();

            await context.ChallengeAsync();

            await context.ForbidAsync();

            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync());

            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync(new ClaimsPrincipal()));
        }
예제 #15
0
        public async Task ServicesWithDefaultSignInMethodsTest()
        {
            var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
            {
                o.AddScheme <SignInHandler>("base", "whatever");
                o.DefaultScheme = "base";
            }).BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = services;

            await context.AuthenticateAsync();

            await context.ChallengeAsync();

            await context.ForbidAsync();

            await context.SignOutAsync();

            await context.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity("whatever")));
        }
예제 #16
0
    public async Task ForwardSchemeOverridesSchemeFromConfig()
    {
        // Arrange
        var defaultSchemeFromConfig  = "DefaultSchemeFromConfig";
        var defaultSchemeFromForward = "DefaultSchemeFromForward";
        var services = new ServiceCollection().AddLogging();
        var config   = new ConfigurationBuilder().AddInMemoryCollection(new[]
        {
            new KeyValuePair <string, string>("Authentication:DefaultScheme", defaultSchemeFromConfig)
        }).Build();

        services.AddSingleton <IConfiguration>(config);

        // Act
        var builder = services.AddAuthentication(o =>
        {
            o.AddScheme <TestHandler>(defaultSchemeFromForward, defaultSchemeFromForward);
        });

        builder.AddJwtBearer(defaultSchemeFromConfig, o => o.ForwardAuthenticate = defaultSchemeFromForward);
        var forwardAuthentication = new TestHandler();

        services.AddSingleton(forwardAuthentication);

        var sp      = services.BuildServiceProvider();
        var context = new DefaultHttpContext();

        context.RequestServices = sp;

        // Assert
        Assert.Equal(0, forwardAuthentication.AuthenticateCount);
        await context.AuthenticateAsync();

        Assert.Equal(1, forwardAuthentication.AuthenticateCount);
        var schemeProvider            = sp.GetRequiredService <IAuthenticationSchemeProvider>();
        var defaultSchemeFromServices = await schemeProvider.GetDefaultAuthenticateSchemeAsync();

        Assert.Equal(defaultSchemeFromConfig, defaultSchemeFromServices.Name);
    }
예제 #17
0
        public async Task SpecificTargetAlwaysWinsOverDefaultTarget()
        {
            var services = new ServiceCollection().AddOptions().AddLogging();

            services.AddAuthentication(o =>
            {
                o.AddScheme <TestHandler>("auth1", "auth1");
                o.AddScheme <TestHandler2>("auth2", "auth2");
            })
            .AddPolicyScheme("forward", "forward", p => {
                p.ForwardDefault         = "auth2";
                p.ForwardDefaultSelector = ctx => "auth2";
                p.ForwardAuthenticate    = "auth1";
                p.ForwardSignIn          = "auth1";
                p.ForwardSignOut         = "auth1";
                p.ForwardForbid          = "auth1";
                p.ForwardChallenge       = "auth1";
            });

            var handler1 = new TestHandler();

            services.AddSingleton(handler1);
            var handler2 = new TestHandler2();

            services.AddSingleton(handler2);

            var sp      = services.BuildServiceProvider();
            var context = new DefaultHttpContext();

            context.RequestServices = sp;

            Assert.Equal(0, handler1.AuthenticateCount);
            Assert.Equal(0, handler1.ForbidCount);
            Assert.Equal(0, handler1.ChallengeCount);
            Assert.Equal(0, handler1.SignInCount);
            Assert.Equal(0, handler1.SignOutCount);
            Assert.Equal(0, handler2.AuthenticateCount);
            Assert.Equal(0, handler2.ForbidCount);
            Assert.Equal(0, handler2.ChallengeCount);
            Assert.Equal(0, handler2.SignInCount);
            Assert.Equal(0, handler2.SignOutCount);

            await context.AuthenticateAsync("forward");

            Assert.Equal(1, handler1.AuthenticateCount);
            Assert.Equal(0, handler2.AuthenticateCount);

            await context.ForbidAsync("forward");

            Assert.Equal(1, handler1.ForbidCount);
            Assert.Equal(0, handler2.ForbidCount);

            await context.ChallengeAsync("forward");

            Assert.Equal(1, handler1.ChallengeCount);
            Assert.Equal(0, handler2.ChallengeCount);

            await context.SignOutAsync("forward");

            Assert.Equal(1, handler1.SignOutCount);
            Assert.Equal(0, handler2.SignOutCount);

            await context.SignInAsync("forward", new ClaimsPrincipal(new ClaimsIdentity("whatever")));

            Assert.Equal(1, handler1.SignInCount);
            Assert.Equal(0, handler2.SignInCount);
        }
예제 #18
0
    public async Task SpecificForwardWinsOverSelectorAndDefault()
    {
        var services = new ServiceCollection().AddLogging();
        var builder  = services.AddAuthentication(o =>
        {
            o.DefaultScheme = DefaultScheme;
            o.AddScheme <TestHandler2>("auth1", "auth1");
            o.AddScheme <TestHandler3>("selector", "selector");
            o.AddScheme <TestHandler>("specific", "specific");
        });

        RegisterAuth(builder, o =>
        {
            o.ForwardDefault         = "auth1";
            o.ForwardDefaultSelector = _ => "selector";
            o.ForwardAuthenticate    = "specific";
            o.ForwardChallenge       = "specific";
            o.ForwardSignIn          = "specific";
            o.ForwardSignOut         = "specific";
            o.ForwardForbid          = "specific";
        });

        var specific = new TestHandler();

        services.AddSingleton(specific);
        var forwardDefault = new TestHandler2();

        services.AddSingleton(forwardDefault);
        var selector = new TestHandler3();

        services.AddSingleton(selector);

        var sp      = services.BuildServiceProvider();
        var context = new DefaultHttpContext();

        context.RequestServices = sp;

        await context.AuthenticateAsync();

        Assert.Equal(1, specific.AuthenticateCount);

        await context.ForbidAsync();

        Assert.Equal(1, specific.ForbidCount);

        await context.ChallengeAsync();

        Assert.Equal(1, specific.ChallengeCount);

        if (SupportsSignOut)
        {
            await context.SignOutAsync();

            Assert.Equal(1, specific.SignOutCount);
        }
        else
        {
            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync());
        }

        if (SupportsSignIn)
        {
            await context.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity("whatever")));

            Assert.Equal(1, specific.SignInCount);
        }
        else
        {
            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync(new ClaimsPrincipal()));
        }

        Assert.Equal(0, forwardDefault.AuthenticateCount);
        Assert.Equal(0, forwardDefault.ForbidCount);
        Assert.Equal(0, forwardDefault.ChallengeCount);
        Assert.Equal(0, forwardDefault.SignInCount);
        Assert.Equal(0, forwardDefault.SignOutCount);
        Assert.Equal(0, selector.AuthenticateCount);
        Assert.Equal(0, selector.ForbidCount);
        Assert.Equal(0, selector.ChallengeCount);
        Assert.Equal(0, selector.SignInCount);
        Assert.Equal(0, selector.SignOutCount);
    }
예제 #19
0
    public async Task CanForwardDefault()
    {
        var services = new ServiceCollection().AddLogging();

        var builder = services.AddAuthentication(o =>
        {
            o.DefaultScheme = DefaultScheme;
            o.AddScheme <TestHandler>("auth1", "auth1");
        });

        RegisterAuth(builder, o => o.ForwardDefault = "auth1");

        var forwardDefault = new TestHandler();

        services.AddSingleton(forwardDefault);

        var sp      = services.BuildServiceProvider();
        var context = new DefaultHttpContext();

        context.RequestServices = sp;

        Assert.Equal(0, forwardDefault.AuthenticateCount);
        Assert.Equal(0, forwardDefault.ForbidCount);
        Assert.Equal(0, forwardDefault.ChallengeCount);
        Assert.Equal(0, forwardDefault.SignInCount);
        Assert.Equal(0, forwardDefault.SignOutCount);

        await context.AuthenticateAsync();

        Assert.Equal(1, forwardDefault.AuthenticateCount);

        await context.ForbidAsync();

        Assert.Equal(1, forwardDefault.ForbidCount);

        await context.ChallengeAsync();

        Assert.Equal(1, forwardDefault.ChallengeCount);

        if (SupportsSignOut)
        {
            await context.SignOutAsync();

            Assert.Equal(1, forwardDefault.SignOutCount);
        }
        else
        {
            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignOutAsync());
        }

        if (SupportsSignIn)
        {
            await context.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity("whatever")));

            Assert.Equal(1, forwardDefault.SignInCount);
        }
        else
        {
            await Assert.ThrowsAsync <InvalidOperationException>(() => context.SignInAsync(new ClaimsPrincipal()));
        }
    }