public async Task KentorAuthServicesAuthenticationMiddleware_UsesCommandResultLocation() { // For Owin middleware, the redirect uri is part of the // authentication properties, but we don't want to use it as it // is because it can be empty (e.g. on unsolicited responses // or until #182 is fixed). The redirect uri should be taken // from the commandresult location instead. var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))) }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/AuthServices/Acs"); var middleware = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(), new KentorAuthServicesAuthenticationOptions(true) { SignInAsAuthenticationType = "AuthType" }); await middleware.Invoke(context); context.Response.StatusCode.Should().Be(302); context.Response.Headers["Location"].Should().Be("http://localhost/LoggedIn"); }
public async Task KentorAuthServicesAuthenticationMiddleware_AcsWorks() { var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var state = new StoredRequestState(new EntityId("https://idp.example.com"), new Uri("http://localhost/LoggedIn"), new Saml2Id(MethodBase.GetCurrentMethod().Name + "RequestID"), new AuthenticationProperties()); ((AuthenticationProperties)state.RelayData).RedirectUri = state.ReturnUrl.OriginalString; ((AuthenticationProperties)state.RelayData).Dictionary["Test"] = "TestValue"; var relayState = RelayStateGenerator.CreateSecureKey(); PendingAuthnRequests.Add(relayState, state); var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"" InResponseTo=""" + MethodBase.GetCurrentMethod().Name + @"RequestID"" > <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))), new KeyValuePair<string, string>("RelayState",relayState) }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/AuthServices/Acs"); var signInAsAuthenticationType = "AuthType"; var ids = new ClaimsIdentity[] { new ClaimsIdentity(signInAsAuthenticationType), new ClaimsIdentity(signInAsAuthenticationType) }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com")); ids[1].AddClaim(new Claim(ClaimTypes.Role, "RoleFromClaimsAuthManager", null, "ClaimsAuthenticationManagerStub")); var middleware = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(), StubFactory.CreateOwinOptions()); await middleware.Invoke(context); context.Response.StatusCode.Should().Be(302); context.Response.Headers["Location"].Should().Be("http://localhost/LoggedIn"); context.Authentication.AuthenticationResponseGrant.Principal.Identities .ShouldBeEquivalentTo(ids, opt => opt.IgnoringCyclicReferences()); context.Authentication.AuthenticationResponseGrant.Properties.RedirectUri .Should().Be("http://localhost/LoggedIn"); context.Authentication.AuthenticationResponseGrant.Properties.Dictionary["Test"] .Should().Be("TestValue"); }
public async Task KentorAuthServicesAuthenticationMiddleware_AcsWorks() { var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = ""KentorAuthServicesAuthenticationMiddleware_AcsWorks"" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""KentorAuthServicesAuthenticationMiddleware_AcsWorks_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))) }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/Saml2AuthenticationModule/acs"); var signInAsAuthenticationType = "AuthType"; var ids = new ClaimsIdentity[] { new ClaimsIdentity(signInAsAuthenticationType), new ClaimsIdentity(signInAsAuthenticationType) }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com")); ids[1].AddClaim(new Claim(ClaimTypes.Role, "RoleFromClaimsAuthManager", null, "ClaimsAuthenticationManagerMock")); var middleware = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(), new KentorAuthServicesAuthenticationOptions() { SignInAsAuthenticationType = "AuthType" }); await middleware.Invoke(context); context.Response.StatusCode.Should().Be(302); context.Response.Headers["Location"].Should().Be("http://localhost/LoggedIn"); context.Authentication.AuthenticationResponseGrant.Principal.Identities.ShouldBeEquivalentTo(ids, opt => opt.IgnoringCyclicReferences()); }
public async Task KentorAuthServicesAuthenticationMiddleware_AcsWorks() { var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var authProps = new AuthenticationProperties() { IssuedUtc = new DateTime(1975, 05, 05, 05, 05, 05, DateTimeKind.Utc) }; authProps.Dictionary["Test"] = "TestValue"; var state = new StoredRequestState(new EntityId("https://idp.example.com"), new Uri("http://localhost/LoggedIn"), new Saml2Id("InResponseToId"), authProps.Dictionary); var relayState = SecureKeyGenerator.CreateRelayState(); var cookieData = HttpRequestData.ConvertBinaryData( CreateAppBuilder().CreateDataProtector( typeof(KentorAuthServicesAuthenticationMiddleware).FullName) .Protect(state.Serialize())); context.Request.Headers["Cookie"] = $"Kentor.{relayState}={cookieData}"; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"" InResponseTo=""InResponseToId"" > <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))), new KeyValuePair<string, string>("RelayState",relayState) }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/AuthServices/Acs"); var signInAsAuthenticationType = "AuthType"; var ids = new ClaimsIdentity[] { new ClaimsIdentity(signInAsAuthenticationType), new ClaimsIdentity(signInAsAuthenticationType) }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com")); ids[1].AddClaim(new Claim(ClaimTypes.Role, "RoleFromClaimsAuthManager", null, "ClaimsAuthenticationManagerStub")); var subject = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(), StubFactory.CreateOwinOptions()); await subject.Invoke(context); context.Response.StatusCode.Should().Be(303); context.Response.Headers["Location"].Should().Be("http://localhost/LoggedIn"); context.Response.Headers["Set-Cookie"].Should().Be($"Kentor.{relayState}=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"); context.Authentication.AuthenticationResponseGrant.Principal.Identities .ShouldBeEquivalentTo(ids, opt => opt.IgnoringCyclicReferences()); context.Authentication.AuthenticationResponseGrant.Properties.RedirectUri .Should().Be("http://localhost/LoggedIn", "the StoredRequestState.ReturnUrl should overtake the value in the AuthProperties and be stored in the AuthProps"); context.Authentication.AuthenticationResponseGrant.Properties.Dictionary["Test"] .Should().Be("TestValue"); context.Authentication.AuthenticationResponseGrant.Properties.IssuedUtc .Should().Be(authProps.IssuedUtc); }
public async Task KentorAuthServicesAuthenticationMiddleware_Acs_HonorsSessionNotOnOrAfter() { var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + $@"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> <saml2:AuthnStatement AuthnInstant=""{DateTime.UtcNow.ToSaml2DateTimeString()}"" SessionNotOnOrAfter=""2050-01-01T00:00:00Z""> <saml2:AuthnContext> <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef> </saml2:AuthnContext> </saml2:AuthnStatement> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))), }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/AuthServices/Acs"); var options = StubFactory.CreateOwinOptions(); var subject = new KentorAuthServicesAuthenticationMiddleware( null, CreateAppBuilder(), options); await subject.Invoke(context); context.Authentication.AuthenticationResponseGrant.Properties .AllowRefresh.Should().BeFalse("AllowRefresh should be false if SessionNotOnOrAfter is specified"); context.Authentication.AuthenticationResponseGrant.Properties .ExpiresUtc.Should().BeCloseTo( new DateTimeOffset(2050, 1, 1, 0, 0, 0, new TimeSpan(0)), because: "SessionNotOnOrAfter should be honored."); }
public async Task KentorAuthServicesAuthenticationMiddleware_Acs_HonorsCommandResultHandled() { var context = OwinTestHelpers.CreateOwinContext(); context.Request.Method = "POST"; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var bodyData = new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("SAMLResponse", Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)))), }; var encodedBodyData = new FormUrlEncodedContent(bodyData); context.Request.Body = encodedBodyData.ReadAsStreamAsync().Result; context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString(); context.Request.Host = new HostString("localhost"); context.Request.Path = new PathString("/AuthServices/Acs"); var options = StubFactory.CreateOwinOptions(); options.Notifications.AcsCommandResultCreated = (cr, r) => { cr.HandledResult = true; }; var subject = new KentorAuthServicesAuthenticationMiddleware( null, CreateAppBuilder(), options); await subject.Invoke(context); context.Response.StatusCode.Should().Be(200); }
private async static Task WriteForm(HttpListenerResponse response, FormHttpBody form) { response.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); var content = new FormUrlEncodedContent(form.Values); var data = await content.ReadAsStreamAsync(); await data.CopyToAsync(response.OutputStream); response.OutputStream.Close(); }