public async Task RetrieveAccessToken_InvalidCertificate_ReturnsUnauthorized()
        {
            var options = new OioIdwsAuthorizationServiceOptions
            {
                AccessTokenIssuerPath            = new PathString("/accesstoken/issue"),
                AccessTokenRetrievalPath         = new PathString("/accesstoken"),
                IssuerAudiences                  = () => Task.FromResult(new IssuerAudiences[0]),
                TrustedWspCertificateThumbprints = new[] { "other cert" },
                CertificateValidator             = X509CertificateValidator.None //no reason for tests to validate certs
            };

            X509Certificate2 certificate = null;

            using (var server = TestServerWithClientCertificate.Create(() => certificate, app =>
            {
                app.UseOioIdwsAuthorizationService(options);
            }))
            {
                server.BaseAddress = new Uri("https://localhost/");

                //without presenting certificate
                var response = await server.HttpClient.GetAsync($"/accesstoken?accesstoken1");

                Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);

                //with untrusted certificate
                certificate = CertificateUtil.GetCertificate("d9f10c97aa647727adb64a349bb037c5c23c9a7a");
                response    = await server.HttpClient.GetAsync($"/accesstoken?accesstoken1");

                Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
            }
        }
示例#2
0
        private async Task ProcessAuthenticateAsync(
            string tokenType,
            Func <IOwinContext, Func <Task>, Task> serviceUnderTest,
            Func <HttpResponseMessage, Task> assert,
            Func <OioIdwsToken> tokenFunc = null,
            Func <OioIdwsToken, ClaimsIdentity> identityFunc = null,
            Func <X509Certificate2> certificateFunc          = null)
        {
            var accessToken = "token123";
            var token       = tokenFunc != null?tokenFunc() : new OioIdwsToken();

            var tokenProviderMock = new Mock <ITokenProvider>();

            tokenProviderMock.Setup(x => x.RetrieveTokenAsync(accessToken))
            .ReturnsAsync(new RetrieveTokenResult(token));

            var identityBuilderMock = new Mock <IIdentityBuilder>();

            identityBuilderMock.Setup(x => x.BuildIdentityAsync(token))
            .Returns((OioIdwsToken t) => Task.FromResult(identityFunc?.Invoke(t)));

            using (var server = TestServerWithClientCertificate.Create(certificateFunc, app =>
            {
                app
                .UseOioIdwsAuthentication(new OioIdwsAuthenticationOptions
                {
                    TokenProvider = tokenProviderMock.Object,
                    IdentityBuilder = identityBuilderMock.Object
                })
                .Use((context, next) => serviceUnderTest(context, next));
            }))
            {
                var client     = server.HttpClient;
                var authHeader = new AuthenticationHeaderValue(tokenType, accessToken);
                client.DefaultRequestHeaders.Authorization = authHeader;
                var response = await client.PostAsync("/securedendpoint", new StringContent("payload"));

                await assert(response);
            }

            tokenProviderMock.Verify(x => x.RetrieveTokenAsync(accessToken), Times.Once);
        }
示例#3
0
        async Task PerformValidationTestAsync(
            X509Certificate2 clientCertificate,
            IEnumerable <IssuerAudiences> issuerAudiences,
            Func <OioIdwsAuthorizationServiceOptions, HttpResponseMessage, Task> assert,
            Func <string> samlToken         = null,
            Func <ILoggerFactory> setLogger = null)
        {
            var requestSamlToken = samlToken != null?samlToken() : GetSamlTokenXml();

            var options = new OioIdwsAuthorizationServiceOptions
            {
                AccessTokenIssuerPath    = new PathString("/accesstoken/issue"),
                AccessTokenRetrievalPath = new PathString("/accesstoken"),
                IssuerAudiences          = () => Task.FromResult(issuerAudiences.ToArray()),
                CertificateValidator     = X509CertificateValidator.None //no reason for tests to require proper certificate validation
            };

            using (var server = TestServerWithClientCertificate.Create(() => clientCertificate, app =>
            {
                app.UseOioIdwsAuthorizationService(options);

                if (setLogger != null)
                {
                    app.SetLoggerFactory(setLogger());
                }
            }))
            {
                server.BaseAddress = new Uri("https://localhost/");

                var response = await server.HttpClient.PostAsync("/accesstoken/issue",
                                                                 new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair <string, string>("saml-token", Utils.ToBase64(requestSamlToken)),
                }));

                await assert(options, response);
            }
        }
        public async Task RetrieveAccessToken_Success_TokenInformationIsInResponse()
        {
            var wspCertificate = CertificateUtil.GetCertificate("d9f10c97aa647727adb64a349bb037c5c23c9a7a");

            var accessToken     = "dummy";
            var oioIdwsTokenKey = "accesstoken1";
            var token           = new OioIdwsToken
            {
                Type       = AccessTokenType.Bearer,
                ExpiresUtc = DateTime.UtcNow.AddHours(1),
                Claims     = new[]
                {
                    new OioIdwsClaim
                    {
                        Type      = "type1",
                        Value     = "value1",
                        ValueType = "valuetype1",
                        Issuer    = "issuer1",
                    },
                    new OioIdwsClaim
                    {
                        Type      = "type2",
                        Value     = "value2",
                        ValueType = "valuetype2",
                        Issuer    = "issuer2",
                    },
                }
            };

            var tokenStoreMock = new Mock <ISecurityTokenStore>();

            tokenStoreMock
            .Setup(x => x.RetrieveTokenAsync(oioIdwsTokenKey))
            .ReturnsAsync(token);

            var tokenDataFormatMock = new Mock <ISecureDataFormat <AuthenticationProperties> >();

            tokenDataFormatMock
            .Setup(x => x.Unprotect(accessToken))
            .Returns(new AuthenticationProperties
            {
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
                Dictionary = { { "value", oioIdwsTokenKey } }
            });

            var options = new OioIdwsAuthorizationServiceOptions
            {
                AccessTokenIssuerPath            = new PathString("/accesstoken/issue"),
                AccessTokenRetrievalPath         = new PathString("/accesstoken"),
                IssuerAudiences                  = () => Task.FromResult(new IssuerAudiences[0]),
                SecurityTokenStore               = tokenStoreMock.Object,
                TokenDataFormat                  = tokenDataFormatMock.Object,
                TrustedWspCertificateThumbprints = new[] { "d9f10c97aa647727adb64a349bb037c5c23c9a7a" },
                CertificateValidator             = X509CertificateValidator.None //no reason for tests to validate certs
            };

            using (var server = TestServerWithClientCertificate.Create(() => wspCertificate, app =>
            {
                app.UseOioIdwsAuthorizationService(options);
            }))
            {
                server.BaseAddress = new Uri("https://localhost/");

                var response = await server.HttpClient.GetAsync($"/accesstoken?{accessToken}");

                Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
                Assert.AreEqual("application/json", response.Content.Headers.ContentType.MediaType);
                var responseToken = JsonConvert.DeserializeObject <OioIdwsToken>(await response.Content.ReadAsStringAsync());

                Assert.AreEqual(token.Type, responseToken.Type);
                Assert.AreEqual(token.ExpiresUtc, responseToken.ExpiresUtc);
                Assert.AreEqual(token.Claims.Count, responseToken.Claims.Count);
                Assert.AreEqual(token.Claims.ElementAt(0).Type, responseToken.Claims.ElementAt(0).Type);
                Assert.AreEqual(token.Claims.ElementAt(0).Value, responseToken.Claims.ElementAt(0).Value);
            }
        }
        public async Task RetrieveAccessToken_ExpiredAccessToken_ReturnsUnauthorized()
        {
            var wspCertificate = CertificateUtil.GetCertificate("d9f10c97aa647727adb64a349bb037c5c23c9a7a");

            var accessToken     = "accessToken1";
            var oioIdwsTokenKey = "tokenValue1";

            var tokenInformation = new OioIdwsToken();

            var authProperties = new AuthenticationProperties
            {
                Dictionary = { { "value", oioIdwsTokenKey } }
            };

            var tokenDataFormatMock = new Mock <ISecureDataFormat <AuthenticationProperties> >();

            tokenDataFormatMock
            .Setup(x => x.Unprotect(accessToken))
            .Returns(() => authProperties);

            var currentTime = DateTimeOffset.UtcNow; //ensure static time during test

            var timeMock = new Mock <ISystemClock>();

            // ReSharper disable once AccessToModifiedClosure
            timeMock
            .SetupGet(x => x.UtcNow)
            .Returns(() => currentTime);

            var storeMock = new Mock <ISecurityTokenStore>();

            storeMock
            .Setup(x => x.RetrieveTokenAsync(oioIdwsTokenKey))
            .Returns(() => Task.FromResult(tokenInformation));

            var options = new OioIdwsAuthorizationServiceOptions
            {
                AccessTokenIssuerPath            = new PathString("/accesstoken/issue"),
                AccessTokenRetrievalPath         = new PathString("/accesstoken"),
                IssuerAudiences                  = () => Task.FromResult(new IssuerAudiences[0]),
                TrustedWspCertificateThumbprints = new[] { "d9f10c97aa647727adb64a349bb037c5c23c9a7a" },
                CertificateValidator             = X509CertificateValidator.None, //no reason for tests to validate certs
                TokenDataFormat                  = tokenDataFormatMock.Object,
                SystemClock        = timeMock.Object,
                MaxClockSkew       = TimeSpan.FromMinutes(5),
                SecurityTokenStore = storeMock.Object,
            };

            using (var server = TestServerWithClientCertificate.Create(() => wspCertificate, app =>
            {
                app.UseOioIdwsAuthorizationService(options);
            }))
            {
                server.BaseAddress = new Uri("https://localhost/");

                {
                    //test that token content is checked properly
                    authProperties.ExpiresUtc = currentTime - options.MaxClockSkew.Add(TimeSpan.FromSeconds(1));

                    var response = await server.HttpClient.GetAsync($"/accesstoken?{accessToken}");

                    Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
                    var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                    Assert.AreEqual(1, json["expired"].Value <int>());
                }

                {
                    //test that stored token information is checked properly
                    authProperties.ExpiresUtc   = currentTime;
                    tokenInformation.ExpiresUtc = currentTime - options.MaxClockSkew.Add(TimeSpan.FromSeconds(1));

                    var response = await server.HttpClient.GetAsync($"/accesstoken?{accessToken}");

                    Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
                    var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                    Assert.AreEqual(1, json["expired"].Value <int>());
                }
            }
        }