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); } }
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); }
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>()); } } }