Ejemplo n.º 1
0
        private static async Task <AzureAuthenticationHandler> CreateAzureAuthenticationHandler(string principal, string authProvider)
        {
            AzureAuthenticationOptions options = new AzureAuthenticationOptions();
            IOptionsMonitor <AzureAuthenticationOptions> optionsMonitor = Substitute.For <IOptionsMonitor <AzureAuthenticationOptions> >();

            optionsMonitor.CurrentValue.Returns(options);

            ILoggerFactory logger  = Substitute.For <ILoggerFactory>();
            UrlEncoder     encoder = Substitute.For <UrlEncoder>();
            ISystemClock   clock   = new SystemClock();

            HeaderDictionary headers = new HeaderDictionary
            {
                { "X-MS-CLIENT-PRINCIPAL-IDP", authProvider },
                { "X-MS-CLIENT-PRINCIPAL", principal }
            };

            HttpContext context = Substitute.For <HttpContext>();

            context.Request.Headers.Returns(headers);
            context.Request.Scheme.Returns("https");
            context.Request.Host.Returns(new HostString("test.com"));

            AuthenticationScheme scheme = new AuthenticationScheme(AzureAuthenticationDefaults.AuthenticationScheme, AzureAuthenticationDefaults.DisplayName, typeof(AzureAuthenticationHandler));

            AzureAuthenticationHandler handler = new AzureAuthenticationHandler(optionsMonitor, logger, encoder, clock);
            await handler.InitializeAsync(scheme, context);

            return(handler);
        }
        public async Task AuthenticateAsync_WhenAccessTokenExpired_ThenAccessTokenRefreshed()
        {
            // Arrange
            string authMeResponse = "[{'access_token': '', 'user_id': '*****@*****.**', 'user_claims': [{'typ': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', 'val': 'Fred' }]}]";
            string graphResponse  = "{'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#groups(id,displayName,securityEnabled)','value': [{'id': 'e73a963b-059e-45e4-acb1-f3fe748f93a4','displayName': 'TestGroup','securityEnabled': true}]}";

            MockHttpMessageHandler authMessageHandler = new MockHttpMessageHandler();

            authMessageHandler
            .Expect(HttpMethod.Get, "https://test.com/.auth/refresh")
            .Respond(HttpStatusCode.OK);

            authMessageHandler
            .Expect(HttpMethod.Get, "https://test.com/.auth/me")
            .Respond("application/json", authMeResponse);

            MockHttpMessageHandler graphMessageHandler = CreateStandardGraphMessageHandler(graphResponse);

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(-5));

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

            // Assert
            result.Succeeded.Should().BeTrue();
            authMessageHandler.VerifyNoOutstandingExpectation();
        }
        public async Task AuthenticateAsync_WhenUserKnown_ThenSuccessfulAuthentication()
        {
            // Arrange
            string authMeResponse = "[{'access_token': '', 'user_id': '*****@*****.**', 'user_claims': [{'typ': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', 'val': 'Fred' }]}]";
            string graphResponse  = "{'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#groups(id,displayName,securityEnabled)','value': [{'id': 'e73a963b-059e-45e4-acb1-f3fe748f93a4','displayName': 'TestGroup','securityEnabled': true}]}";
            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMeResponse, graphResponse, DateTime.Now.AddMinutes(30));

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

            // Assert
            result.Succeeded.Should().BeTrue();
            result.Ticket.Principal.Identity.Name.Should().Be("*****@*****.**");
            result.Ticket.Principal.HasClaim(c => c.Type == ClaimTypes.GivenName && c.Value == "Fred");
            result.Ticket.Principal.HasClaim(c => c.Type == Constants.GroupsClaimType && c.Value == "e73a963b-059e-45e4-acb1-f3fe748f93a4");
        }
        public async Task AuthenticateAsync_WhenAuthMeJsonInvalid_ThenAuthenticationFails()
        {
            // Arrange
            string authMeResponse = "[{'access_token': '',";
            MockHttpMessageHandler authMessageHandler = CreateStandardAuthMessageHandler(authMeResponse);

            MockHttpMessageHandler graphMessageHandler = CreateStandardGraphMessageHandler("");

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(5));

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

            // Assert
            result.Succeeded.Should().BeFalse();
        }
        public async Task AuthenticateAsync_WhenGraphCallReturnsInvalidJson_ThenAuthenticationFails()
        {
            // Arrange
            string authMeResponse = "[{'access_token': '', 'user_id': '*****@*****.**', 'user_claims': [{'typ': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', 'val': 'Fred' }]}]";
            MockHttpMessageHandler authMessageHandler = CreateStandardAuthMessageHandler(authMeResponse);

            string graphResponse = "{'@odata.context': ";
            MockHttpMessageHandler graphMessageHandler = CreateStandardGraphMessageHandler(graphResponse);

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(5));

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

            // Assert
            result.Succeeded.Should().BeFalse();
        }
Ejemplo n.º 6
0
        public async Task AuthenticateAsync_WhenUserKnown_ThenSuccessfulAuthentication()
        {
            // Arrange
            string groupId      = Guid.NewGuid().ToString();
            string authprovider = "EasyAuthProvider";
            string principal    = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{{'auth_typ':'{authprovider}','claims':[{{'typ':'{ClaimTypes.Name}','val':'*****@*****.**'}}, {{'typ':'{Constants.GroupsClaimType}','val':'{groupId}'}}, {{'typ':'{ClaimTypes.GivenName}','val':'Fred'}}],'name_typ':'','role_typ':''}}"));
            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(principal, authprovider);

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

            // Assert
            result.Succeeded.Should().BeTrue();
            result.Principal.HasClaim(c => c.Type == "AuthenticationProvider" && c.Value == "EasyAuthProvider");
            result.Ticket.Principal.Identity.Name.Should().Be("*****@*****.**");
            result.Ticket.Principal.HasClaim(c => c.Type == ClaimTypes.GivenName && c.Value == "Fred");
            result.Ticket.Principal.HasClaim(c => c.Type == Constants.GroupsClaimType && c.Value == groupId);
        }
        private static async Task <AzureAuthenticationHandler> CreateAzureAuthenticationHandler(MockHttpMessageHandler authMessageHandler, MockHttpMessageHandler graphMessageHandler, DateTime accessTokenExpiryTime)
        {
            AzureAuthenticationOptions options = new AzureAuthenticationOptions();
            IOptionsMonitor <AzureAuthenticationOptions> optionsMonitor = Substitute.For <IOptionsMonitor <AzureAuthenticationOptions> >();

            optionsMonitor.CurrentValue.Returns(options);

            ILoggerFactory logger  = Substitute.For <ILoggerFactory>();
            UrlEncoder     encoder = Substitute.For <UrlEncoder>();
            ISystemClock   clock   = new SystemClock();

            HttpClient authHttpClient = authMessageHandler.ToHttpClient();

            HttpClient graphHttpClient = graphMessageHandler.ToHttpClient();

            IHttpClientFactory httpClientFactory = Substitute.For <IHttpClientFactory>();

            httpClientFactory
            .CreateClient(Arg.Is(AzureAuthenticationHandler.AzureAuthenticationHttpClientName))
            .Returns(authHttpClient);
            httpClientFactory
            .CreateClient(Arg.Is(AzureAuthenticationHandler.GraphHttpClientName))
            .Returns(graphHttpClient);

            HeaderDictionary headers = new HeaderDictionary
            {
                { "X-MS-TOKEN-AAD-EXPIRES-ON", accessTokenExpiryTime.ToString() }
            };

            HttpContext context = Substitute.For <HttpContext>();

            context.Request.Headers.Returns(headers);
            context.Request.Scheme.Returns("https");
            context.Request.Host.Returns(new HostString("test.com"));

            AuthenticationScheme scheme = new AuthenticationScheme(AzureAuthenticationDefaults.AuthenticationScheme, AzureAuthenticationDefaults.DisplayName, typeof(AzureAuthenticationHandler));

            AzureAuthenticationHandler handler = new AzureAuthenticationHandler(optionsMonitor, logger, encoder, clock, httpClientFactory);
            await handler.InitializeAsync(scheme, context);

            return(handler);
        }
        public async Task AuthenticateAsync_WhenGraphCallFails_ThenAuthenticationFails()
        {
            // Arrange
            string authMeResponse = "[{'access_token': '', 'user_id': '*****@*****.**', 'user_claims': [{'typ': 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', 'val': 'Fred' }]}]";
            MockHttpMessageHandler authMessageHandler = CreateStandardAuthMessageHandler(authMeResponse);

            MockHttpMessageHandler graphMessageHandler = new MockHttpMessageHandler();

            graphMessageHandler
            .When("https://graph.microsoft.com/v1.0/me/memberOf/$/microsoft.graph.group?$select=id,displayName,securityEnabled")
            .Respond(HttpStatusCode.BadRequest);

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(5));

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

            // Assert
            result.Succeeded.Should().BeFalse();
        }
        public async Task AuthenticateAsync_WhenAuthMeCallFails_ThenAuthenticationFails()
        {
            // Arrange
            MockHttpMessageHandler authMessageHandler = new MockHttpMessageHandler();

            authMessageHandler
            .When(HttpMethod.Get, "https://test.com/.auth/refresh")
            .Respond(HttpStatusCode.OK);

            authMessageHandler
            .When(HttpMethod.Get, "https://test.com/.auth/me")
            .Respond(HttpStatusCode.BadRequest);

            MockHttpMessageHandler graphMessageHandler = CreateStandardGraphMessageHandler("");

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(5));

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

            // Assert
            result.Succeeded.Should().BeFalse();
        }
        public async Task AuthenticateAsync_WhenAccessTokenExpired_AndRefreshFails_ThenAuthenticationFails()
        {
            // Arrange
            MockHttpMessageHandler authMessageHandler = new MockHttpMessageHandler();

            authMessageHandler
            .Expect(HttpMethod.Get, "https://test.com/.auth/refresh")
            .Respond(HttpStatusCode.BadRequest);

            var authMeRequest = authMessageHandler
                                .When(HttpMethod.Get, "https://test.com/.auth/me")
                                .Respond(HttpStatusCode.OK);

            MockHttpMessageHandler graphMessageHandler = CreateStandardGraphMessageHandler("");

            AzureAuthenticationHandler handler = await CreateAzureAuthenticationHandler(authMessageHandler, graphMessageHandler, DateTime.Now.AddMinutes(-5));

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

            // Assert
            result.Succeeded.Should().BeFalse();
            authMessageHandler.GetMatchCount(authMeRequest).Should().Be(0, "Auth Me call should not be called");
        }